我不知道为什么未执行的闭包可以捕获外部变量。
我确实读过一些关于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
当引擎执行到第 7 行时,foo execution context
是在global execution context
之上创建的,但是在第 7 行之后,闭包从未被执行过,因此从未创建过闭包执行上下文,词汇环境也是如此。foo execution context
被弹出,变量a
将被释放。
我找不到我的观点有什么问题。 那么为什么以及何时捕获闭包中的变量呢?
function foo() {
var a = 1;
return function() {
console.log(a);
}
}
函数内部的函数称为闭包。当一个函数内部有另一个函数时,
假设顶级函数在这种情况下有一些像"a"这样的数据,那么所有内部函数都将访问该数据,只有当内部函数有一些关于这些变量的引用时,才会发生这种情况。
假设你在"a"旁边有"b"变量,并且你没有在内部函数的任何地方使用它,这将被javascript简单地忽略。"闭包"不会像"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
希望这有帮助。
谢谢。
这是关于 bugs.chromium 的讨论,与您的问题相关。根据这一点,即使 else 块从未执行过,对 else 块返回的函数中使用的外部对象的引用也会被创建并存储在堆中。它永远不会被垃圾回收。请参阅下面的讨论:-
https://bugs.chromium.org/p/chromium/issues/detail?id=315190
关键点是词法范围:
词法作用域是 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