5

这是来自JavaScript 闭包如何工作?. 第一个答案对我来说零意义,我无法评论。非常令人沮丧

function foo(x) {
  var tmp = 3;
  return function(y) {
    alert(x + y + (++tmp));
  }
}
var bar = foo(2); // bar is now a reference to the closure returned by foo
bar(10);

这是什么意思?y变量从何而来?

4

3 回答 3

4

对于变量的来源:

function foo(x) {       // x introduced
  var tmp = 3;          // tmp introduced
  return function (y) { // y introduced
    // Can access all variables in scope, as introduced above.
    // However, ONLY x and tmp are closed-over as y is just a parameter
    // to the inner function.
    alert(x + y + (++tmp));
  }
}

var bar = foo(2);  // 2 is value for x
bar(10);           // 10 is value for y

现在,再深入一点:

foo(2)返回一个的函数对象(内部函数),它绑定到两个变量(x 当前值为 2,tmp 当前值为 3)。

然后bar(10) 运行传入 10(即 y 的值)的函数对象。

重复调用bar(10)将导致不同的值,因为在函数调用期间tmp重新分配了封闭变量( )。++tmp

于 2013-06-30T22:38:08.627 回答
3

您需要区分变量(包含信息的内存的名称)和参数(要传递给函数的变量的占位符)。(实际上它在函数原型中称为形参,在函数体中使用时称为实参。)所以y不是现有变量,而是要传入的变量(或值)的占位符。

然后,您需要了解它var func = function(){}变成func了对匿名函数(没有名称的函数)的引用。一个简化的例子是:

var func = function (y) {
   alert(y);
}
func("hello");

你可以从那开始。其他一切都与嵌套方式中应用的原理相同。

于 2013-06-30T22:41:02.970 回答
0

foo正在返回一个函数,该函数接受一个名为y.

因此,当您调用 foo 时,您会返回一个函数,您可以随时使用参数执行该函数,该参数将成为y.

请注意,返回的函数是匿名的,但作为foo返回它,您可以有效地将函数绑定到变量。在这里,foo被调用,返回值被分配给bar

现在,您可能会问“好吧,如果函数 return 有参数y,我调用了bar(10),现在y给定了值10,但现在是什么x

嗯,x已经有一个值,它在foo第一次被调用时得到。这是一个“工作流程”表示。

  1. 定义了一个被调用foo的函数,它接受一个参数x。它返回一个匿名函数,该函数接受一个名为y.
  2. 该函数以等于 2foo的值被调用,并且它的返回值被绑定到. 现在是对匿名函数的引用,其中 x 的所有值都等于被调用的值,即 2。xbarbarx foo
  3. 当绑定到的匿名函数bar被调用时bar(10),参数y被赋予值10bar执行以下

    警报(2 + 10 +(++tmp));

所以你现在可能会问,“那么 tmp 是什么”?好吧,如果您遵循上述内容,那应该可以相当简单地推断出来。当匿名函数从 中返回时foo,对绑定到值的本地变量的任何引用foo都有

于 2013-06-30T22:40:39.043 回答