在JavaScript中使用闭包时千万要搞清楚作用域链

作者:admin     字体:[增加 减小]    类型:原创
在JavaScript中要特别小心那些不希望共享的变量往往不经意间共享给了其他的闭包。关联到闭包的作用域链都是“活动的”,记住这一点非常重要。嵌套的函数不会将作用域内的私胡成员复制一份,也不会对所绑定的变量生成静态快照。

在JavaScript中要特别小心那些不希望共享的变量往往不经意间共享给了其他的闭包,了解这一点很重要,看一下下面这段代码:

//这个函数返回一个总是返回v的函数
function constfunc(v){return function(){return v;}}

//创建一个数组用来存储常数函数
var funcs = [];
for(var i=0;i<10;i++ ) funcs[i] = constfunc(i);

//在第5个位置的元素所表示的函数返回值为5
console.log(funcs[5]());

这段代码利用循环创建了很多个闭包,当写类似这种代码的时候往往犯一个错误,那就是试图将循环代码移入定义这个闭包的函数之内,看一下这段代码:

function constfuncs(){
    var funcs = [];
    for(var i = 0;i<10;i++ ) {
        funcs[i] = function(){return i;}
    }
    return funcs;
}

var funcs = constfuncs();
console.log(funcs[5]());    //10

上面这段代码创建了10个闭包,并将它们存储到一个数组中。这些闭包都是在同一个函数调用中定义的,因此它们可以共享变量i。当constfuncs()返回时,变量i的值是10,所有的闭包都共享这一个值,因此,数组中的函数的返回值都是同一值,这不是我们想要的结果。关联到闭包的作用域链都是“活动的”,记住这一点非常重要。嵌套的函数不会将作用域内的私胡成员复制一份,也不会对所绑定的变量生成静态快照(static snapshot)。