我有以下代码:
var x = 6;
var y = 4;
var a = function(b) {
return function(c) {
return y + b + c;
}
};
x = 2;
y = 5;
var fn = a(x);
x = 1;
y = 3;
为了让fn(unknown)
输出10,我被要求弄清楚需要什么未知:
console.log(fn(unknown)); // This should output 10
我知道未知需要为5才能使fn输出为10,但是有人可以解释为什么吗?
我确定它与机箱有关,但不太了解如何在不同阶段分配变量。
答案 0 :(得分:3)
我听过的最简单的闭包描述是:
这是一种函数可以无限制地访问其创建环境的方法。
所以:
var a = function(b) { /* "outer" aka "functionofb" */
return function(c) { /* "inner" aka "functionofc" */
return y + b + c;
}
};
我们将会看到这是如何让内部函数无限期地访问(内部)变量'b'的副本,因为它存在于内在的生命中。 (在此示例中,内部函数永远不会更改其'b'副本的值,但它可以。)
因此,为了完成您的示例,让我们从这里开始:
x = 2;
var fn = a(x);
变量a“指向”未命名的(匿名)函数(带有'b'作为arg的那个),所以这基本上是:
fn = functionofb(x);
或:
fn = functionofb(2);
现在'functionofb'是一个返回函数的函数。它返回的函数是:
function(c) {
return y + b + c;
}
(这也是匿名的,所以我们称之为`functionofc')
所以:
function(c) {
return y + 2 + c; /* here 'b's value is 'captured' by the closure */
}
然后我们有:
y = 3;
并做:
fn(5);
这只是:
functionofc(5);
给了我们:
return y + 2 + c;
或者:
return 3 + 2 + 5; /* 'y' was never captured, the current value is used */
哪个是理想的答案:
10
其他一切都只是红色的鲱鱼。
有关JavaScript 闭包的更全面讨论,请参阅How do JavaScript closures work?
答案 1 :(得分:2)
当你这样做时......
var fn = a(x);
......变量fn
等于......
function(c) {
return y + 2 + c;
}
...因为此时x
等于2,执行函数x
时捕获(固定)a
的值。
因此,当您在运行函数fn(5)
的那一刻执行变量y
等于3的fn
时,这意味着函数将执行此操作。
return 3 + 2 + 5;
由于3 + 2 + 5 = 10,这意味着您的输出为10.
fn(5)
之前运行了 y = 3;
,则会返回12,因为此时y
的值为5。有关演示,请参阅this Fiddle。
有关闭包的更多信息,请参阅此问题:
答案 2 :(得分:1)
您需要将5
作为unknown
传递。
- 闭包是函数的局部变量 - 在函数返回后保持活动状态,或
- 一个闭包是一个堆栈框架,当函数返回时它没有被释放(好像一个'堆栈框架'是malloc'而不是在堆栈上!)。
传递给b
的{{1}}参数保存在a()
返回的闭包中。因此,在您的示例中,a
被保存为b
或x
的值。这是因为javascript中的2
s是按值传递的。这意味着更改Number
不会更改x
返回的闭包内b
的值。
清晰的简短例子:
a

闭包中的var a = function(x) {
return function() {
return x + 1;
};
};
var x1 = 1;
var fn1 = a(x1); // x1 is passed by value, so x inside the closure is its own copy of 1
x1 = 2 // no effect on the next line
console.log(fn1()) // prints 2, does NOT print 3
变量y
直接从全局范围返回引用a
,因此全局范围中y
的更改会改变{的值y
返回的闭包中的{1}}。
简洁示例:
y

a
是一个副本,对于整个示例保留2,var x = 1;
var a = function() {
return x + 1;
};
console.log(a()); // prints 2, since x is still 1
x = 2;
console.log(a()); // prints 3, since the a() closure references the global x
引用一个全局变量,可能会在调用b
后更改它的值,并y
1}}将是a()
的值,因为它是c
返回的闭包的参数。
完整性的例子:
unknown