麻省理工学院开放课程的JavaScript示例

时间:2015-02-10 06:14:41

标签: javascript

有人可以解释这是如何得到50,以及该算法是如何工作的。感谢。

var multipliers = function makeMultipliers (max) { 
    var result = [];
    for (var i = 0; i < max; i++)
        result.push (function (x) {return x * i;}); 
    return result;
}

multipliers(10) [2] (5)
???

有什么价值?

50,而不是5

你可以解决它吗?

来源:http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-170-software-studio-spring-2013/lecture-notes/MIT6_170S13_35-java-fn-cls.pdf

第30页

2 个答案:

答案 0 :(得分:0)

此代码创建一个函数数组,这些函数将错误地全部引用i的最终值,但这些函数旨在在每次迭代期间冻结i的值。

要修复它,您只需通过嵌入一个新的局部变量,在另一个函数中冻结i的值,就可以为迭代变量添加一个局部性级别。例如,在现有局部变量i下面作为参数传递给虚函数,并且该时刻的i值被冻结到独立的新局部变量i中原始i的原始i并未因原始result.push (function (x) {return x * i;}) result.push((function(i) { return function (x) {return x * i;}; })(i)); 的后续迭代而改变。

{{1}}

答案 1 :(得分:0)

这是一个范围问题。在调用最后一个函数时,i是最后一次在该范围内看到的位置,即10。您可以通过闭包来防止这种情况。

function multipliers(max){
  var a = [];
  for(var i=0; i<max; i++){
    (function(i){
      a.push(function(x){return x*i});
    })(i);
  }
  return a;
}

在这种情况下,闭包是一个自动执行的函数,可以在循环的每一步调整i。如果没有发生这种情况,范围将转到multipliers函数本身。由于循环已经在您调用传递5的函数时已经完成,该函数恰好位于2返回的数组的multipliers处,{{1} }已经达到i。显然,10 * 5是50.当使用闭包时10的最后位置是i在它所在的范围内,为你提供所寻求的结果。 5 * 2 = 10。

2