繁体   English   中英

非法阴影(Shadowing let with var)

[英]Illegal Shadowing (Shadowing let with var)

考虑以下 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在全局 scope 中声明, let a在块 scope 中。 但是为什么这在第一种情况下无效? 在那里, let a将在单独的 scope 中声明,而var a应在全局 scope 中声明。 为什么这个案子无效?

但是为什么这在第一种情况下无效?

因为这两个声明都在同一个 scope中。¹您的第二个示例有效,因为let仅适用于块,而不是存在var a的块之外的 scope 。 (就像 function 中的局部变量一样。)所以在第二个示例中,它是阴影。 在第一个示例中,它不会是阴影,而是重复,这是您无法使用let做的(即使其他声明使用var )。 (您可以使用var在同一个 scope 中多次声明一个变量。随后的var被忽略,尽管变量上的任何初始化程序都被转换为赋值。例如, var a; var a = 42;var a; a = 42;相同var a; a = 42; )


¹ 好的,从技术上讲,它比这要复杂一些。 var变量存在于“外部”全局词法环境中,该环境在全局 object 上保存绑定(松散地,变量),但let变量存在于“内部”全局词法环境中,该环境不保持其在全局 object 上的绑定。 全局 scope 仍然只是一个 scope,所以正如你所见,你不能在全局 scope 上同时拥有var alet 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"

有趣的事实:根据您的计算方式,在浏览器上,“全局”环境有两到六层

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM