【问题标题】:cannot create javascript closure无法创建 javascript 闭包
【发布时间】:2013-04-22 11:53:02
【问题描述】:

尝试在 test.tgt 中创建与 test.src 中的函数相同的函数,但它们将具有上下文。

test.src.fn() => test.work.fn.call(context)

这里是测试台

var fn1 = function() { console.log('fn1'); }; var fn2 = function() { console.log('fn2'); }; var 上下文 = { a: 1 }; 变种测试 = { tgt:{}, src:{一:fn1,二:fn2}, 初始化:函数(){ for( var i in test.src ) { test.tgt[i] = function(arg) { test.src[i].call(test.cxt,arg); }; } } } 测试.init(); test.src.one() => 'fn1' test.tgt.one() => 'fn2' 哎哟!!

问题在于 test.src[i] 在函数执行之前不会被评估。

如何在新创建的函数中获得“真实的”test.src[i]

【问题讨论】:

标签: javascript syntax scope closures


【解决方案1】:

尝试为循环的每次迭代创建一个闭包:

var fn1 = function() { console.log( 'fn1' ); }; 
var fn2 = function() { console.log( 'fn2' ); }; 
var context = { a: 1 };
var test = {
  tgt: {},
  src: { one: fn1, two: fn2 },
  init: function() {
    for( var i in test.src ) {
      test.tgt[i] = (function(index){return function(arg) { test.src[index].call(test.cxt,arg); };}(i));
    }
  }
}
test.init();
test.src.one() // => 'fn1'
test.tgt.one() // => 'fn1'

【讨论】:

    【解决方案2】:

    这是一个经典的 Javascript 问题。您假设 for 循环上下文中的 i 应该被捕获为创建函数时的值,但它是 i 的最后一个值。为了解决这个问题,您可以像这样在本地捕获它:

    test.tgt[i] = (function(local_i){
        return function(arg) { test.src[local_i].call(test.cxt,arg); };
    })(i);
    

    所以你将它包装在一个立即执行的函数上下文中,并且内部函数在该迭代中获得正确的 i 值。

    【讨论】:

      【解决方案3】:

      您在init 中创建的所有函数都有共享闭包,因此它们共享i 变量,因此它始终是最后一个。试试这个:

      init: function() {
          for( var i in test.src ) {
            (function(idx) { 
                test.tgt[idx] = function(arg) {test.src[idx].call(test.cxt,arg); };
            }(i));
          }
      }
      

      【讨论】:

      猜你喜欢
      • 2016-01-30
      • 2016-05-31
      • 2021-01-03
      • 2016-11-21
      • 1970-01-01
      • 2012-09-16
      • 1970-01-01
      • 2014-05-26
      • 1970-01-01
      相关资源
      最近更新 更多