IllegalShadowing(Shadowingletwithvar)
考虑以下 JavaScript 中的阴影示例:
let a = 99;
{
var a = 10;
let b = 11;
const c = 200;
console.log(a);
}
console.log(a);
在这里,我收到以下错误:
SyntaxError: Identifier 'a' has already been declared
但在以下情况下,没有语法错误,代码完全有效。
var a = 99;
{
let a = 10;
let b = 11;
const c = 200;
console.log(a);
}
console.log(a);
在第二种情况下var a在全局范围内声明并且let a在块范围内。但是为什么这在第一种情况下无效?在那里,let a将在单独的范围内声明,并var a应在全局范围内声明。为什么本案无效?
回答
但是为什么这在第一种情况下无效?
因为这两个声明都在同一个范围内。¹您的第二个示例有效,因为let范围仅限于块,而不是var a存在于块之外的范围。(就像函数中的局部变量。)所以在第二个例子中,它是阴影。在第一个示例中,它不会是阴影,而是重复,这是您无法处理的let(即使其他声明使用var)。(您可以使用var在同一范围内多次声明一个变量。随后的vars 将被忽略,尽管该变量上的任何初始值设定项都被转换为赋值。例如,var a; var a = 42;与 相同var a; a = 42;)
¹ 好的,从技术上讲,它比那要复杂一些。var变量存在于“外部”全局词法环境中,该环境持有全局对象上的绑定(松散地,变量),但let变量存在于“内部”全局词法环境中,该环境不持有其对全局对象的绑定。全局作用域仍然只是一个作用域,所以正如您所见,不能同时拥有var a和let a两者都处于全局作用域,因为它们相互冲突。但是还有其他方法可以创建“外部”全局变量,例如分配给window(或this在全局范围内,或globalThis在现代环境中)的属性:
// At global scope
window.a = 42; // Creates binding in the outer global environment
console.log(a); // Shows 42
这意味着可以在外部和内部全局词法环境中创建绑定:
// At global scope
window.a = 42; // Creates binding in the outer global environment
let a = "answer"; // Creates binding in the inner global environment
console.log(a); // Shows "answer"
由于内部更接近执行该操作的代码console.log(a),因此上述输出"answer".
有趣的事实:根据您的计算方式,在浏览器上,“全局环境”有两到六层。
THE END
二维码