关于闭包经常会看到这么一道题:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());//result:The Window
《javascript高级程序设计》一书给出的解释是:
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。不过,匿名函数具有全局性,因此this对象同常指向window
关于作用域链,闭包的问题:
- a()函数内嵌套了b()函数,外部调用a函数时不执行b函数:
- <script>
function outer(){
var result = new Array();
for(var i = 0; i < 2; i++){
result[i] = function(){
return i;
}
}
return result;
}
var fn = outer();
console.log(fn[0]());//result:2
console.log(fn[1]());//result:2
</script>
fn=outer();时,return的是result数组,result=[ function result[ 0 ]() {return i; }, function result[ 1 ]() {return i; } ]
在console.log( fn[0]() )时,才执行 function result[0 ]{ return i} 这个函数,但是在result[0 ]()执行环境对象中找不到变量i ,于是利用作用域链向上,在父级outer()函数执行环境中找到了i,此时i已经变成了2。
一般来说,当某个环境中的所有代码执行完毕后,该环境被销毁(弹出环境栈),保存在其中的所有变量和函数也随之销毁(全局执行环境变量直到应用程序退出,如网页关闭才会被销毁)
但是像上面那种有内部函数的又有所不同,当outer()函数执行结束,执行环境被销毁,但是其关联的活动对象 i 并没有随之销毁,而是一直存在于内存中,因为该活动对象被其内部函数的作用域链所引用。
像上面这种内部函数的作用域链仍然保持着对父函数活动对象的引用,就是闭包(closure)
所以闭包有两个作用:
第一个就是可以读取自身函数外部的变量(沿着作用域链寻找)
第二个就是让这些外部变量始终保存在内存中
result[ i]=function (){ return i }; 相当于 function result[ i] (){ return i;} 所以在outer() 函数中仅仅是进行定义,并未执行,要想执行,可以这样写:
result [ i]=function (){ return i } (i );
本文通过示例深入解析JavaScript中的闭包概念及其工作原理,包括如何利用作用域链来访问外部变量。

被折叠的 条评论
为什么被折叠?



