闭包
当你看见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
同样可以访问到x和tmp,尽管它们不在直接存在于作用域中。不过,因为
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"
我们可以创建多个闭包方法实例,它们将会指向同一个x与tmp,而不是复制这些参数出来。
在下面例子中,
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