闭包

当你看见function里面又嵌套着一个function,而内嵌的function又访问了外部的变量时,那就是闭包,如下代码:

 

1 function foo(x){var tmp =3;function bar(y){
2     alert(x + y +(++tmp));// will alert 16}
3 
4   bar(10);}
5 
6 foo(2);
 
以上的代码将会弹窗出16.因为bar可以访问到foo中定义的 x,也可以访问到tmp变量.
 
这就是一个闭包。在函数作用域内访问外部变量就会生成一个闭包。

 

function foo(x){var tmp =3;returnfunction(y){
    alert(x + y +(++tmp));// will also alert 16}}var bar = foo(2);// bar is now a closure.
bar(10);

 

 
上面的代码同样会弹窗出16, bar同样可以访问到xtmp,尽管它们不在直接存在于作用域中。
 
不过,因为tmp 仍旧存在于bar的闭包中,每一次调用bar,它将会自增。
 
 
请看下面的闭包例子:
 

1 var a =10;
2 function test(){
3   console.log(a);// will output 10
4   console.log(b);// will output 6
5 }
6 var b =6;
7 test();
 
当一个JavaScript方法被调用时,一个新的执行环境将会被创立。包括了方法的参数以及父亲对象,执行环境也同样包括了外部定义的参数,例如上例的"a"与"b"
 
我们可以创建多个闭包方法实例,它们将会指向同一个xtmp,而不是复制这些参数出来。
 
 
在下面例子中, x是一个语义上的数字。当 foo 被调用,x的值将会传输到foo 中。
 
 
另一方面,JavaScript在处理函数时总是引用访问。也就是说,当你调用 foo时,闭包返回的还是原本的对象。

 

1 function foo(x){var tmp =3;returnfunction(y){
2     alert(x + y + tmp);
3     x.memb = x.memb ? x.memb +1:1;
4     alert(x.memb);}}var age =newNumber(2);var bar = foo(age);// bar is now a closure referencing age.
5 bar(10);
 
如预期一样,每一次调用bar(10)都会增加x.memb的值。而 x引用的是age 对象。
 
参考:http://stackoverflow.com/questions/111102/how-do-javascript-closures-work
 
原文地址:https://www.cnblogs.com/deryck/p/4178612.html