简体   繁体   English

无法创建javascript闭包

[英]cannot create javascript closure

trying to create functions in test.tgt the same as the functions in test.src except that they will will have a context. 努力打造功能test.tgt一样的功能test.src除了他们将有一个背景。

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

here is the test bed 这是测试床

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!!

the problem is that test.src[i] is not evaluated until the function is executed. 问题是在执行该函数之前不会评估test.src[i]

how do I get the "real" test.src[i] inside the newly created function? 如何在新创建的函数中获取“真实的” test.src[i]

Try creating a closure for each iteration of the loop: 尝试为循环的每次迭代创建一个闭包:

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'

This is a classic Javascript issue. 这是经典的Javascript问题。 You assume that i in the context of the for loop should be captured as the value when the function was created, but instead it is the last value of i. 您假定在for循环的上下文中i应该作为函数创建时的值捕获,但它是i的最后一个值。 To get round this, you can locally capture it like so: 为了解决这个问题,您可以像这样在本地捕获它:

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

So you wrap it in a function context which is executed immediately and the inner function gets the correct value of i for that iteration. 因此,将其包装在立即执行的函数上下文中,内部函数将为该迭代获取i的正确值。

All functions you created inside init have shared closure, so they share i variable, thus it is always the last. 您在init内创建的所有函数均具有共享的闭包,因此它们共享i变量,因此它始终是最后一个。 Try this: 尝试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM