JavaScript|JavaScript之匿名函数和闭包

有多人在学习JavaScript时混淆了闭包和匿名函数,下面我们来区分这两个概念
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一、变量的作用域
理解匿名函数和闭包,首先理解JavaScript独特的变量作用域。
来看看下面的代码:

var a=1; function outer() { alert(a); } outer(); //1

以上函数outer() 内可以访问外部的全局变量a。

function outer() { var a= 1; } alert(a); //error

以上函数outer() 外不能访问函数内的局部变量a。

匿名函数是利用这点,使函数外部环境无法访问函数内的局部变量;
闭包用来解决使函数外部环境可以访问函数内的局部变量。

二、匿名函数
1.定义:简单说就是没有指定函数名的函数。
2.创建方法:有三种创建匿名函数的方法:
(1)(function() {})(); //最为常见
(2)(function(){}());
(3)void function(){};
(4)function(){}(); //错误的写法
原因:如果需要创建匿名函数,则必须给出一个函数表达式而非函数的显式声明。(1)(2)(3)匿名函数代码模式只不过是通过括号或者void告诉编译器,把function(){}当作函数表达式来解释罢了。这其中并没有那么复杂 的优先级和void操作符原理。这只不过是一个简单的语法转换。
以上三种创建方法相当于创建一个函数,并立即自执行,相当于如下代码:

function XXX(){ //运行代码段 } XXX();


3. 作用:在全局作用域中可以通过匿名函数形成一个私有作用域,外部无法访问函数内的变量,对内部起到安全保护作用。写法如下:

(function() { //这里是私有作用域 })();




三、闭包
1. 定义:有权访问一个函数作用域中的变量的函数。
2. 创建方法:通常在一个函数内部创建另一个函数。
如下代码:


function outer() { var a = 1; return function inner() { alert(a); } } var result = outer(); result(); //1


以上在函数outer() 内创建并返回了一个函数inner() ,该函数内可以访问outer() 的局部变量a,从而形成闭包。
在outer() 外部,将闭包inner() 储存于result中,运行result() 就是运行inner() ,输出预期值1。
3. 闭包通常用匿名函数来创建。可以将上述代码修改为:

function outer() { var a = 1; return function() { alert(a); } } var result = outer(); result(); //1


运行结果仍然相同。因此开发中常用匿名函数创建闭包,两者在概念上并不等价!
4. 注意:
(1)执行闭包时所有的全局变量都将存入内存,这会占用大量内存,影响网页性能,因此要慎重使用闭包。
【JavaScript|JavaScript之匿名函数和闭包】(2)闭包容易造成隐蔽的循环引用,从而导致内存泄露的问题,有关细节将在下一节详述。

    推荐阅读