为什么以及何时未执行的闭包可以捕获javascript中的外部变量?



我不知道为什么未执行的闭包可以捕获外部变量。

我确实读过一些关于execute contextlexical environmentmemory 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

最新更新