在循环中设置javascript defineGetter和defineSetter

时间:2010-08-24 15:42:14

标签: javascript

为什么每次迭代都这样:

var o = {};

var foo = [['a',1],['b',2],['c',3],['d',4],['e',5]];

for(var i = 0; i < 5; i++)
{
  o.__defineGetter__(foo[i][0], function() {
    return foo[i][1]; 
  });
  console.info(JSON.stringify(o));
}

重置以前的所有作业并输出:

{"a":1}
{"a":2,"b":2}
{"a":3,"b":3,"c":3}
{"a":4,"b":4,"c":4,"d":4}
{"a":5,"b":5,"c":5,"d":5,"e":5}

当我期望/想要完成的是:

{"a":"1","b":"2","c":"3","d":"4","e":"5"}

我如何实现我的目标?

2 个答案:

答案 0 :(得分:2)

您需要创建一个函数来返回一个能够执行您想要的函数(这只是因为闭包在JavaScript中的工作方式)。这个例子应该可行。

var o = {};

var foo = [['a',1],['b',2],['c',3],['d',4],['e',5]];

var getFunc = function(val){
    return function() {
        return val; 
    }
};

for(var i = 0; i < 5; i++)
{
  var func = getFunc(foo[i][1]);
  o.__defineGetter__(foo[i][0], func);
}
console.info(JSON.stringify(o));

答案 1 :(得分:1)

这是因为闭包的工作方式。变量的作用域是它们定义的函数。没有循环变量这样的东西(除非你使用的是具有let关键字的JS版本)。因此,在循环结束时,i的值在您定义的所有匿名函数中都是相同的。你可以通过在循环结束时输出i来看到这一点:

for(var i = 0; i < 5; i++)
{
  o.__defineGetter__(foo[i][0], function() {
    return foo[i][1]; 
  });
  console.info(JSON.stringify(o));
}
console.info(i); //outputs 5

编辑:正如所指出的,这是同一个问题,就像这个问题:JavaScript closure inside loops – simple practical example