如何在javascript中获取闭包中变量的值

时间:2014-01-17 22:00:59

标签: javascript closures

我正在创建一个这样的回调数组:

function createFunctions(n) {
  var callbacks = [];

  for (var i=0; i<n; i++) {
    callbacks.push(function() {
      return i;
    });
  }

  return callbacks;
}

而且,这是我正在进行的测试:

var callbacks = createFunctions(5);

for (var i=0; i<callbacks.length; i++) {
  Test.assertEquals(callbacks[i](), i, 'Function with index ' + i);
}

基本上,我希望回调在数组中返回它的索引(即callback[1]()应该返回1)。但是,当测试运行时,createFunctions中定义的i设置为6,因此它们总是返回6.我已经尝试创建一个局部变量来保存匿名函数中的值,但这也不起作用。

任何想法如何使这项工作?

1 个答案:

答案 0 :(得分:2)

闭包有一个持久引用到它关闭的变量,而不是它们创建时的值的副本。这就是为什么你的所有函数都会看到6:这就是i在调用这些函数时的值。

如果您需要它们来查看不同的值,请使闭包关闭不会发生变化的其他内容。这是一种方式:

function createFunctions(n) {
    var callbacks = [];

    for (var i=0; i<n; i++) {
      callbacks.push(makeCallback(i));
    }

    return callbacks;

    function makeCallback(index) {
        return function() {
          return index;
        };
    }
}

或者:

function createFunctions(n) {
    var callbacks = [];

    for (var i=0; i<n; i++) {
      callbacks.push(makeCallback(i));
    }

    return callbacks;

}

function makeCallback(index) {
    return function() {
      return index;
    };
}

(在此示例中,makeCallback是在createFunctions之内还是在index之外并不重要。)

现在,回调关闭了包含makeCallback参数的上下文。他们每个人都获得了该上下文的自己的副本(通过调用index函数创建),因此没有任何变化function allocator(start) { return function() { return ++start; }; } var f = allocator(0); alert(f()); // "1" alert(f()); // "2" alert(f()); // "3" ,其值保持不变。

更多(在我的博客上)Closures are not complicated

关闭变量上下文的闭包的这个特性是非常非常有用的。考虑:

allocator

如果start创建的函数包含allocator的副本,则无效。它的工作原理是因为{{1}}创建的函数有一个引用(通过上下文)变量本身。