0

尝试创建与 in 中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]在新创建的函数中获得“真实”?

4

3 回答 3

2

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

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'
于 2013-04-22T11:59:23.290 回答
2

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

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

因此,您将其包装在立即执行的函数上下文中,并且内部函数在该迭代中获得 i 的正确值。

于 2013-04-22T12:01:08.033 回答
1

您在内部创建的所有函数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));
    }
}
于 2013-04-22T11:59:10.053 回答