我不明白为什么一个未执行的闭包可以捕获外部变量。
我确实读过一些关于execute context、lexical environment、memory management的文章,但这些都不能解决我的问题:
function foo() {
var a = 1;
return function() {
console.log(a);
}
}
var f = foo() // line 7
// HERE variable a was been captured
f = undefined // line 10
// HEAE variable a was been released当引擎执行line7时,在global execution context之上创建了foo execution context,但在line7之后,从未执行过闭包,因此从未创建过闭包执行上下文,词法环境也是如此。弹出了foo execution context,将释放变量a。
我找不到我的观点有什么问题。那么为什么以及何时捕获闭包中的变量呢?
发布于 2019-08-30 15:46:02
function foo() {
var a = 1;
return function() {
console.log(a);
}
}函数内部的函数称为闭包。
当一个函数内部有另一个函数时,假设顶级函数有一些数据,比如本例中的'a‘,那么所有内部函数都将访问这些数据,只有当内部函数有一些关于这些变量的引用时,才会发生这种情况。
比方说,如果你在'a‘旁边有'b’变量,并且你在内部函数中的任何地方使用它,而不是,这将被javascript忽略。“‘Closure”不会像“a”那样保存此值。
这实际上是闭包赋予开发人员力量的地方。
看看下面的例子--
const test = (num1) => (num2) => console.log(num1*num2);//closure is in action here
var s = test(100)
s(2); // this will give output of 200希望这能有所帮助。
谢谢。
发布于 2019-08-30 16:24:37
这里是与您的问题相关的bugs.chromium上的讨论。这样,即使else块从未执行过,也会创建对由else块返回的函数中使用的外部对象的引用,并将其存储在堆中。它永远不会被垃圾回收。请参阅以下讨论:
https://bugs.chromium.org/p/chromium/issues/detail?id=315190
发布于 2019-09-01 22:10:01
关键点是词法作用域
词法作用域是JavaScript语言使用的作用域模型,它不同于其他一些使用动态作用域的语言。词法作用域是词法分析时定义的作用域。
考虑到这个问题:
var a = 1
console.log(a)
console.log(b)
var b = 2
console.log(c)您可以获得以下结果:
1
undefinded
ReferenceError: c is not defined因此,您可以看到JavaScript是如何处理变量的:所有变量都在词法分析时定义,并在运行时赋值。这就是他们所说的吊装。
回到问题:闭包在词法分析时捕获变量,在这个时候js引擎读取你的代码,定义变量并绑定它们。
有关编译的更多信息,请访问:https://v8.dev/blog/background-compilation
https://stackoverflow.com/questions/57721489
复制相似问题