尝试在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 context = { a: 1 }; var test = { tgt: {}, src: { one: fn1, two: fn2 }, init: function() { for( var i in test.src ) { test.tgt[i] = function(arg) { test.src[i].call(test.cxt,arg); }; } } } test.init(); test.src.one() => 'fn1' test.tgt.one() => 'fn2' ouch!!
问题是在执行函数之前不会评估test.src[i]
。
如何获得"真实" test.src[i]
在新创建的函数中?
答案 0 :(得分: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'
答案 1 :(得分:2)
这是一个经典的Javascript问题。您假设for循环的上下文中的i
应该被捕获为创建函数时的值,而不是它的最后一个值。为了解决这个问题,您可以在本地捕获它:
test.tgt[i] = (function(local_i){
return function(arg) { test.src[local_i].call(test.cxt,arg); };
})(i);
所以你将它包装在一个立即执行的函数上下文中,内部函数为该迭代获得正确的i值。
答案 2 :(得分: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));
}
}