首页 > 编程语言 > NodeJS > JavaScript 闭包的理解
2014
12-11

JavaScript 闭包的理解

关于闭包,阮一峰的这篇文章 写得比较清晰易懂。 不过需要注意的是闭包不是函数,而是函数的作用域。由于 JavaScript 的作用域不是由 block 符号 {} 来界定,而是函数,所以两者容易混淆。阮一峰说闭包是函数估计是帮助大家理解吧。

以上是他最后的思考题。因为闭包内的函数只能访问闭包内的变量,所以 this 必须要赋给 that 才能引用。

作用域

JavaScript 的闭包其实是一个作用域(scope),而这个作用域就是闭包内部的函数可以访问和修改变量的范围(注意因为闭包是外部函数的 {} 划定的作用域,所以提到函数时一般是指 {} 大括号内部申明的函数)。换句话说,闭包允许一个函数访问内部的所有变量和其他函数,只要这个函数是在这个闭包的作用域内申明的。

一个函数可以访问含有自身申明的闭包的原始作用域。

闭包作用域:

  • 函数的参数在函数的闭包作用域内。
  • 所有在函数自身作用域(函数的{})外的变量,甚至那些在函数申明之后申明的变量,都可以在函数内引用。

使用时注意闭包的开销,可能会影响性能。阮的文章有解释。

闭包的一个常用功能就是封装变量,类似其他语言的私有变量,来限制变量的作用域,不污染全局作用域。

我们也可以通过闭包内的函数来修改闭包内的变量值。所以,闭包不是一个简单的固定状态,而是可以随时改变的封装。

函数的偏应用(Partially Applying Function)

偏应用就是为一个多元函数(接受多个参数的函数)在调用前指定部分参数,从而在调用时可以省略这些参数。实际上,偏应用化一个函数就是返回一个预定义参数的新函数。 这种使用返回函数预先提供前几个参数的的技术叫做科里化(currying)。

立即被执行的函数

这个函数会被立即执行,而不仅仅是定义。

在这个 <code>(…)()</code> 立即执行函数里,第一对括号只是分隔号,就像 <code>(3+2) * 4</code> 的括号功能一样。不过第二对括号是操作符,类似 <code>var sum = add(1,2);</code> 的括号。

this

在对象中,调用变量必须使用 this,不然会调用到对象外的全局同名变量。 在函数中,this 是函数所属的对象。如果使用 ‘use strict’, 函数里的 this 会变为 undefined。一般只有在初始函数(Constructor) 里才使用 this。

注意:闭包里没有 this 参数,因为每个函数调用有自己的 this。

在阮的思考题里,我们可以使用 bind 来达到目的。

‘use strict’

尽量在 js 文件开始处使用 ‘use strict’ 来减少陷入 JavaScript 里暗藏的坑。比如下面的代码就在 strict 模式下不允许。

在闭包里使用循环

需要注意的一点: 闭包和循环如果同时使用的话有时会有问题,因为闭包内的变量是保存变化的,如果创建闭包之后再使用函数的话,循环里的 i 可能会一直是最后一个值(比如最大值)。

最后编辑:
作者:Carmen
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。