我目前正在学习 Javascript 范围,并尝试为正在发生的事情制定一些规则。 但每次意想不到的行为都会打破它们。所以我需要帮助。
考虑下面的例子
console.log("v" in this); //true
console.log(v) //undefined
{
{
function a() {
1;
}
}
{
function a() {
2;
}
{
function v() {
3;
}
}
}
}
console.log(a); //ƒ a() {2}
函数 v 在内存中,但我不能在第 2 行使用它。但在这个例子中我可以。
console.log(v);
{
function v() {
1;
}
}
我对编译器在执行脚本之前所做的规则以及评估声明的步骤(顺序)感到困惑,包括使用 let,const,var 和 function 声明和 class 声明。 我读过关于作用域的博客和书籍,但几乎所有这些都将变量、函数和类视为独立的东西,而不是附加在作用域的 D.E.R 中的属性
最佳答案
function
v
is in memory but I can't use it at line 2. But in this example I can
不,两个示例的行为方式相同。在这两种情况下,v
都是在一个 block 内声明的,并且在这两种情况下,它的值都是 undefined
到你记录它的地方。
在松散模式(又名“草率”模式)下,符合特定条件的 block 中的函数声明会在函数(或全局)范围内创建提升绑定(bind)(v
,在这种情况下) ,而不是 block 范围。该绑定(bind)使用值 undefined
进行初始化;直到在代码的逐步执行中到达声明,它才获得分配给它的功能。 还有一个隐藏函数/全局绑定(bind)的 block 局部绑定(bind),它在 block 的开头用函数初始化。是的,这非常令人困惑;这是因为这是将 ES2015 中的规则追溯应用到跨浏览器引擎的通用功能子集,这些浏览器引擎使用 block 声明的函数扩展了 JavaScript(这不在规范中,但是允许的扩展)。
但是,不要依赖它,甚至真的费心去记住它。这是遗留兼容性问题。
相反,使用严格模式,在该模式下,声明成为 block 的局部(在 block 内完全提升)并且您根本不能在 block 外使用 v
:
"use strict";
console.log("v" in this); // false
console.log(v) // ReferenceError
{
{
function a() {
1;
}
}
{
function a() {
2;
}
{
function v() {
3;
}
}
}
}
console.log(a);
关于javascript - Javascript 中的声明式环境记录和范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58823846/