成都计算机培训 网络报名 Java软件开发培训课程 朗沃成都软件Java培训中心师资介绍 成都软件培训学校开班信息 朗沃成都Java软件开发培训学校学员就业情况 Java朗沃成都软件培训中心在线咨询
成都朗沃教育课程升级啦!
□ 您现在的位置:首页> 学员天地> web编程> 正文

JavaScript内核:函数式的Javascript

朗沃成都软件培训学校在线咨询         朗沃成都软件培训学校在线报名

关键词:Javascript

  要说JavaScript和其他较为常用的语言最大的不同是什么,那无疑就是JavaScript是函数式的语言,函数式语言的特点如下:

  函数为第一等的元素,即人们常说的一等公民。就是说,在函数式编程中,函数是不依赖于其他对象而独立存在的(对比与Java,函数必须依赖对象,方法是对象的方法)。

  函数可以保持自己内部的数据,函数的运算对外部无副作用(修改了外部的全局变量的状态等),关于函数可以保持自己内部的数据这一特性,称之为闭包。我们可以来看一个简单的例子:

  Js代码

  var outter = function(){

  var x = 0;

  return function(){

  return x++;

  }

  }

  var a = outter();

  print(a());

  print(a());

  var b = outter();

  print(b());

  print(b());

  运行结果为:

  0

  1

  0

  1

  变量a通过闭包引用outter的一个内部变量,每次调用a()就会改变此内部变量,应该注意的是,当调用a时,函数outter已经返回了,但是内部变量x的值仍然被保持。而变量b也引用了outter,但是是一个不同的闭包,所以b开始引用的x值不会随着a()被调用而改变,两者有不同的实例,这就相当于面向对象中的不同实例拥有不同的私有属性,互不干涉。

  由于JavaScript支持函数式编程,我们随后会发现JavaScript许多优美而强大的能力,这些能力得力于以下主题:匿名函数,高阶函数,闭包及柯里化等。熟悉命令式语言的开发人员可能对此感到陌生,但是使用lisp, scheme等函数式语言的开发人员则觉得非常亲切。

  9.1匿名函数

  匿名函数在函数式编程语言中,术语成为lambda表达式。顾名思义,匿名函数就是没有名字的函数,这个是与日常开发中使用的语言有很大不同的,比如在C/Java中,函数和方法必须有名字才可以被调用。在JavaScript中,函数可以没有名字,而且这一个特点有着非凡的意义:

  Js代码

  function func(){

  //do something

  }

  var func = function(){

  //do something

  }

  这两个语句的意义是一样的,它们都表示,为全局对象添加一个属性func,属性func的值为一个函数对象,而这个函数对象是匿名的。匿名函数的用途非常广泛,在JavaScript代码中,我们经常可以看到这样的代码:

  Js代码

  var mapped = [1, 2, 3, 4, 5].map(function(x){return x * 2});

  print(mapped);

  应该注意的是,map这个函数的参数是一个匿名函数,你不需要显式的声明一个函数,然后将其作为参数传入,你只需要临时声明一个匿名的函数,这个函数被使用之后就别释放了。在高阶函数这一节中更可以看到这一点。

  9.2高阶函数

  通常,以一个或多个函数为参数的函数称之为高阶函数。高阶函数在命令式编程语言中有对应的实现,比如C语言中的函数指针,Java中的匿名类等,但是这些实现相对于命令式编程语言的其他概念,显得更为复杂。

  9.2.1 JavaScript中的高阶函数

  Lisp中,对列表有一个map操作,map接受一个函数作为参数,map对列表中的所有元素应用该函数,最后返回处理后的列表(有的实现则会修改原列表),我们在这一小节中分别用JavaScript/C/Java来对map操作进行实现,并对这些实现方式进行对比:

  Js代码

  Array.prototype.map = function(func /*, obj */){

  var len = this.length;

  //check the argument

  if(typeof func != "function"){

  throw new Error("argument should be a function!");

  }

  var res = [];

  var obj = arguments[1];

  for(var i = 0; i < len; i++){

  //func.call(), apply the func to this[i]

  res[i] = func.call(obj, this[i], i, this);

  }

  return res;

  }

  我们对JavaScript的原生对象Array的原型进行扩展,函数map接受一个函数作为参数,然后对数组的每一个元素都应用该函数,最后返回一个新的数组,而不影响原数组。由于map函数接受的是一个函数作为参数,因此map是一个高阶函数。我们进行测试如下:

  Js代码

  function double(x){

  return x * 2;

  }

  [1, 2, 3, 4, 5].map(double);//return [2, 4, 6, 8, 10]

  应该注意的是double是一个函数。根据上一节中提到的匿名函数,我们可以为map传递一个匿名函数:

  Js代码

  var mapped = [1, 2, 3, 4, 5].map(function(x){return x * 2});

  print(mapped);

  这个示例的代码与上例的作用是一样的,不过我们不需要显式的定义一个double函数,只需要为map函数传递一个“可以将传入参数乘2并返回”的代码块即可。再来看一个例子:

  Js代码

  [

  {id : "item1"},

  {id : "item2"},

  {id : "item3"}

  ].map(function(current){

  print(current.id);

  });

  将会打印:

  item1

  item2

  item3

  也就是说,这个map的作用是将传入的参数(处理器)应用在数组中的每个元素上,而不关注数组元素的数据类型,数组的长度,以及处理函数的具体内容。

 

|<< << < 1 2 3 4 > >> >>|
朗沃成都软件培训学校在线咨询         朗沃成都软件培训学校在线报名
作者: 朗沃IT教育 成都中心
原载:朗沃IT教育 成都中心 lovoinfo.com
版权所有,转载时必须以链接形式注明作者和原始出处及本声明
在线客服
在线客服系统