Understanding javascript closure variable capture in v8(了解V8中的Java脚本闭包变量捕获)
问题描述
我理解闭包保持对变量的引用延长其生命周期的语义,使原始变量不受调用堆栈的限制,因此应该特殊处理由闭包捕获的变量。
我也理解相同作用域中的变量可能会被不同地处理,这取决于它是否被当今的Java脚本引擎中的闭包捕获。例如,
function foo(){
var a=2;
var b=new Array(a_very_big_number).join('+');
return function(){
console.log(a);
};
}
var b=foo();
由于foo
中没有人持有对b
的引用,因此不需要在内存中保留b
,因此可以在foo
返回时立即释放已使用的内存(甚至在进一步优化的情况下永远不会创建)。
我的问题是,为什么V8似乎将所有闭包引用的所有变量打包在每个调用上下文中?例如,
function foo(){
var a=0,b=1,c=2;
var zig=function(){
console.log(a);
};
var zag=function(){
console.log(b);
};
return [zig,zag];
}
zig
和zag
似乎都引用a
和b
,即使b
显然对zig
不可用。当b
非常大,并且zig
持续时间很长时,这可能会很糟糕。
但站在执行的角度,我不能理解为什么这是必须的。根据我的知识,在不调用eval
的情况下,可以在执行之前确定作用域链,从而可以确定引用关系。引擎应该知道,当zig
不再可用时,请执行a
操作,因此引擎会将其标记为垃圾。
Chrome和Firefox似乎都遵守了这一规则。标准是否规定任何实现都必须这样做?还是这样的实施更实用、更高效?我很困惑。
推荐答案
该标准没有说明任何关于垃圾收集的内容,但提供了一些应该发生的事情的线索。 引用:Standard
一个外部词汇环境当然可以有它自己的外部 词汇环境。词汇环境可以作为外部环境 多个内部词汇环境的环境。例如,如果一个 函数声明包含两个嵌套的函数声明 每个嵌套函数的词法环境将具有如下内容 他们的外部词汇环境--当下的词汇环境 执行周围的函数。"
Section 13 Function definition
step 4: "Let closure be the result of creating a new Function object as specified in 13.2"
Section 13.2 "a Lexical Environment specified by Scope" (scope = closure)
Section 10.2 Lexical Environments:
"The outer reference of a (inner) Lexical Environment is a reference to the Lexical Environment that logically surrounds the inner Lexical Environment.
因此,函数将有权访问父级的环境。
这篇关于了解V8中的Java脚本闭包变量捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:了解V8中的Java脚本闭包变量捕获


- 400或500级别的HTTP响应 2022-01-01
- 如何使用 JSON 格式的 jQuery AJAX 从 .cfm 页面输出查 2022-01-01
- CSS媒体查询(最大高度)不起作用,但为什么? 2022-01-01
- Quasar 2+Apollo:错误:找不到ID为默认的Apollo客户端。如果您在组件设置之外,请使用ProvideApolloClient() 2022-01-01
- Css:将嵌套元素定位在父元素边界之外一点 2022-09-07
- addEventListener 在 IE 11 中不起作用 2022-01-01
- 使用RSelum从网站(报纸档案)中抓取多个网页 2022-09-06
- Flexslider 箭头未正确显示 2022-01-01
- 失败的 Canvas 360 jquery 插件 2022-01-01
- Fetch API 如何获取响应体? 2022-01-01