JS:哪些/如何将变量存储在闭包中?

时间:2014-12-08 14:15:47

标签: javascript node.js closures

请考虑以下代码:

    var a = [ { a: 'I' }, { a: 'II' }, { a: 'III' } ];

    for( var i=0; i<a.length; i++ ){

            var j = i;
            var x = a[ i ];

            x.bb = function(){
                    x.b = "-" + x.a + "-";
            }
            x.cc = function(){
                    a[ i ].c = "-" + a[ i ].a + "-";
            }
            x.dd = function(){
                    a[ j ].d = "-" + a[ j ].a + "-";
            }
    }

    for( var i=0; i<a.length; i++ ){
            a[i].bb();
            a[i].cc();
            a[i].dd();
    }

    console.log( a );

将导致(功能遗漏):

[ { a: 'I', c: '-I-' },
  { a: 'II', c: '-II-' },
  { a: 'III', b: '-III-', d: '-III-', c: '-III-' } ]

所以只有cc()做我想做的事。

我现在的问题是:

  1. 这里有什么规则变量存储在闭包中。 (显然i存储为常量,而jx存储为对for循环迭代时更改的局部变量的引用。但为什么会这样? ) 我的错误。代码只起作用,因为第二个和第一个i相同!
  2. 有没有办法以bb()的形式存储对a[ i ]的引用,以便我不必使用索引?
  3. 谢谢!

1 个答案:

答案 0 :(得分:2)

你需要记住,JavaScript没有块范围(好吧,还没有,ES6 is working that in with let),相反,一切都在&#34;功能&#34;水平。也就是说,所有变量的范围都限定在最近的函数定义中。

使用var语句声明变量,根据您的代码,您拥有的每个变量都限定为此代码的外部容器。换句话说,如果此代码是在Node模块中,此处的所有变量都作用于整个模块。因此,尽管在for循环中定义的函数是闭包(因为所有JS函数都是闭包),但它们仍然只是使用模块中定义的变量,因为JS不需要进一步查看

为了说明问题1的答案,请考虑以下事项:

var o = {};
var x = 1;

function foo() {
    var x = 2;
    o.bar = function() {
        console.log(x);
    }
}

o.bar(); // will output "2" because of the closure created in `foo()`

至于你的第二个问题,因为a [i]是一个对象,你赋予该对象的任何变量(在这种情况下,x)将是一个引用,所有引用都将指向同一个对象在记忆中。我不是你用bb()试图完成的事情,但你是&#34;存储对[i]&#34;的引用。使用x。也许你有一个更具体的例子?