当function里嵌套function时,内部的function能够访问外部function里的变量。数组
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(10);
}
foo(2)闭包
无论执行多少次,都会alert 16,由于bar能访问foo的参数x,也能访问foo的变量tmp。函数
但,这还不是闭包。当你return的是内部function时,就是一个闭包。内部function会close-over外部function的变量直到内部function结束。spa
function foo(x) {作用域
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 如今是一个闭包
bar(10);io
上面的脚本最终也会alert 16,由于虽然bar不直接处于foo的内部做用域,但bar仍是能访问x和tmp。function
可是,因为tmp仍存在于bar闭包的内部,因此它仍是会自加1,并且你每次调用bar时它都会自加1.变量
(考虑到六岁这个限制:咱们其实能够创建不止一个闭包方法,好比return它们的数组,也能够把它们设置为全局变量。它们全都指向相同的x和相同的tmp,而不是各自有一份副本。)object
注:如今来整点儿七岁的内容。引用
上面的x是一个字面值(值传递),和JS里其余的字面值同样,当调用foo时,实参x的值被复制了一份,复制的那一份做为了foo的参数x。
那么问题来了,JS里处理object时是用到引用传递的,那么,你调用foo时传递一个object,foo函数return的闭包也会引用最初那个object!
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar 如今是一个引用了age的闭包
bar(10);
不出咱们意料,每次运行bar(10),x.memb都会自加1。但须要注意的是x每次都指向同一个object变量——age,运行两次bar(10)后,age.memb会变成2.