javascript - [[scope]] 键内的块是什么以及它是何时创建的?
问题描述
我尝试了以下代码
let let_arr = [];
for (let i = 0; i < 4; i++) {
let_arr[i] = () => {
return {
let_i: i
}
};
}
console.log(let_arr);
当我们在 for 循环中使用 let 时,我发现 block 键存在。
[ƒ, ƒ, ƒ, ƒ]
0: () => {…}
arguments: (...)
caller: (...)
length: 0
name: ""__proto__: ƒ ()
[[FunctionLocation]]: iif.js:26
[[Scopes]]: Scopes[3]
0: Block {i: 0}
1: Script {let_arr: Array(4), var_arr: Array(4)}
2: Global {window: Window, self: Window, document: document, name: "", location: Location, …}
而使用 var
for (var i = 0; i < 4; i++)
块元素时丢失。
[[Scopes]]: Scopes[2]
0: Script {let_arr: Array(4), var_arr: Array(4)}
1: Global {window: Window, self: Window, document: document, name: "", location: Location, …}
解决方案
Javascript functions are actually closures, that is, when you save a function somewhere, not only its code is retained, but also all variables available at the creation time. Variables are stored in dictionaries called scopes, which can be nested in each other ("scope chain").
In order to conserve memory, the engine only retains scopes that are actually used in the function. If a scope does not contain let/const
, it is considered unused and omitted. If a scope does contain let
, but that variable is not used in the function, it's also omitted. Otherwise the scope is retained and attached to the closure.
A couple of illustrations:
var f
{
var a
f = () => a // Global
}
console.dir(f)
//
{
let a
f = () => a
}
console.dir(f) // Block a + Global
//
{
let a
{
let b
{
let c
f = () => b
}
}
}
console.dir(f) // Block b + Global
//
{
let a
{
let b
{
let c
f = () => eval("b")
}
}
}
console.dir(f) // 'eval' retains everything
推荐阅读
- session - OFBiz 会话过期:FO PDF 下载后
- url - Crystal-lang:如何在重定向后找到结束 URL?
- angular - 查找在 Angular 应用程序中加载 agggrid 时冻结 UI 的 Javascript 代码
- firebase - 链接/取消链接 - Vuejs Firebase - 计算不起作用
- python - Python:用于跨具有不同输入的函数验证键值错误的装饰器
- javascript - JavaScript:按键选择旧数组并重命名新数组中的键
- c++ - VirtualAlloc() 的 _set_new_handler 等价物?
- c# - 忽略自签名证书错误 c# UWP
- r - 在 R 中编写双系列
- angular - 如何通过代码导航到嵌套路由器