函数式JavaScript编程指南

—— 匿名函数

我们将首先介绍匿名函数。一个匿名函数就是一个没有名字的函数。
你可以认为他们是一次性函数。当你只需要用一次某个函数式,他们就特别有用。通过使用匿名函数,没有必要把函数一直放在内存中,所以使用匿名函数更加有效率。

例Example:

下面两个函数处理同样的事情,而average在给z赋值结束之后一直保留——但匿名函数则不会。

1
2
3
4
5
function  average (x ,y )   {
return   (x +y ) / 2 ;
}
var  z   =  average ( 1 , 3 ) ;
alert (z ) ;
1
2
3
4
var  z   =   function (x ,y )   {
return   (x +y ) / 2 ;
}   ( 1 , 3 ) ;
alert (z ) ;

这很自然得引出了我们下面的一节课函数作为值

—— 函数作为值

事实上,我们一般在JavaScript中声明函数的方式可以看作是一个简化了的语法(也就是语法糖syntactic sugar)。

例:

下面两个表达式其实完全一样。所以左边的表达式仅仅是右边的简写。

1
2
3
4
function  average (x ,y )   {
return   (x +y ) / 2 ;
}
alert (  average ( 1 , 3 )   ) ;
1
2
3
4
var  average   =   function (x ,y )   {
return   (x +y ) / 2 ;
}
alert (  average ( 1 , 3 )   ) ;

从这里可以得出一个结论,函数是一个值就像字符串、数字或数组一样。这还出现几个问题:

我是否可以把函数作为参数传递?
可以,见下面的例子。
是否可以实时生成函数?
当然了,这是一个高级的主题,它可以通过 eval函数来完成。 小提示:看看本页面的源代码。


例:
这个例子演示了如何把函数作为参数传递。

1
2
3
4
5
6
7
var  applyFun   =   function   (f ,x ,y )   {   return  f (x ,y ) ;   } ;

var  add   =   function (x ,y )   {
return  x +y ;
} ;

alert (  applyFun (add , 3 , 4 )   ) ;   // 7

—— 两种方式调用函数

在JavaScript中,有两种调用函数的方式。一般的方式是把参数放在括号中,如alert(42)。另一种方式是同时把函数和参数都放在括号中,如(alert)(42)

例:

1
alert ( 42 ) ;
1
( alert )   ( 42 ) ;
1
( function (x )   {   alert (x - 13 ) ;   } )   ( 55 ) ;

为什么函数两边的括号很重要:如果你写了括号,那么在括号中的代码就会被先计算。在计算之后,括号所在的地方就会有一个值。这个值可能是一个字符串、一个数字或一个函数。

—— “短路”条件调用

现在我们将学习如何使用“短路”条件调用。使用这个方法可以缩短源代码同时代码也变得更加可读。

例:

这个语法并不是用在左表达式上,而是用在右表达式上。

1
2
3
4
5
6
var  f   =   false ;   var  t   =   true ; var  z ;
if (f )
z   =   4 ;
else   if (t )
z   =   2 ;
alert (z ) ;
1
2
3
var  f   =   false ;   var  t   =   true ;
var  z   =   (f   &&   4 )   ||   (t   &&   2 ) ;
alert (z ) ;

—— 它好在哪里

OK,现在我们已经学习了一些函数式JavaScript的内容。那么它好在哪里?函数式JavaScript编程之所以很重要有三条主要的理由:

  1. 它有助于写出模块化和可服用的代码。
  2. 它对事件处理程序非常有效。
  3. 它很有趣!

在下面的篇幅中,我会给出更多关于前两条理由的信息

1. 模块化和可复用的代码

现在你已经知道如何将函数作为值使用,那么你也应该试试!一个很好的例子是数组内建的sort方法。预定义的sort()把所有的对象转换成字符串并把他们按照词语的顺序排序。但如果我们有用户自定义的对象或者数字那么它就不是很有用了。于是这个函数可以让你给他一个进行比较的函数作为参数,如sort(compareFunction)。这个方法让我们甚至不用接触实际的sort方法。

例:

1
2
3
4
5
6
7
8
var  myarray   =   new  Array ( 6 , 7 , 9 , 1 ,- 1 ) ;
var  sortAsc   =   function (x ,y )   {   return  x -y ;   } ;
var  sortDesc   =   function (x ,y )   {   return  y -x ;   } ;
myarray. sort (sortDesc ) ;
alert (myarray ) ;

myarray. sort (sortAsc ) ;
alert (myarray ) ;

2. 事件处理程序

对事件处理程序使用函数式编程也许是最直观的函数作为值得应用了。既然这样我们马上就演示一个例子。

简单的例子:;ie

现在有一个Button类,带一个自定义的onclick行为。

1
2
3
4
5
6
function  Button (clickFunction )   {
this. button   =  document. createElement ( "button" ) ;
this. button. appendChild (document. createTextNode ( "Press me!" ) ) ;
this. button. onclick   =  clickFunction ;
}
var  bt   =   new  Button ( function ( )   {   alert ( "42" ) ;   } ) ;

 为什么我们要把alert包裹在一个匿名函数中?

高级例子:

现在我们想改进我们的Button类。每一个按钮都被分配了一个值当按钮被点击时显示该值。首先我们调整我们的类:

1
2
3
4
5
function  Button (value )   {
this. value   =  value ;
this. button   =  document. createElement ( "button" ) ;
this. button. appendChild (document. createTextNode ( "test" ) ) ;
}

下面你也许要尝试写下面的代码:

1
this. button. onclick   =   function ( )   {   alert ( this. value ) ;   } ;

如果你执行它你就会发现提示框中间是空的。为什么会这样呢?其实原因在于JavaScript的可见性规则。当onclick函数被执行时this指向的是按钮的DOM节点而非自定义的按钮对象。

我们如何解决这个问题? 使用函数式编程:

1
2
3
this. button. onclick   =   ( function (v )   {
return   function ( )   {   alert (v ) ;   } ;
} )   ( this. value ) ;

这种情况下执行该匿名函数会将v绑定到this.value上。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值