【问题标题】:Why would let statement behave so much different from var?为什么 let 语句的行为与 var 有很大不同?
【发布时间】:2015-10-21 07:16:06
【问题描述】:

我知道let是声明块作用域局部变量,但是为什么不像var那样支持重声明和提升呢?

这个限制的设计目的是什么?

(function(){
    'use strict';
    alert(a);       // undefined
    var a;
})();

(function(){
    'use strict';
    alert(a);       // error
    let a;
})();

(function(){
    'use strict';
    var a;
    var a;
    alert(a);       // undefined
})();

(function(){
    'use strict';
    let a;
    let a;          // error
    alert(a);
})();

【问题讨论】:

  • @user2190986 但很明显let 没有在 JavaScript 中声明常量
  • @user2190986 const 用于声明常量。
  • let 声明提升。但与 var 声明不同,该变量不会在块的开头使用 undefined 进行初始化。
  • In fact let declarations are hoisted。重新声明几乎总是一个错误(可能在 REPL 中除外),所以它们现在是一个错误。

标签: javascript ecmascript-6


【解决方案1】:

我们的想法是创建一个比原来的var 更明确、更严格的工具。

作为人类,以下是有效的 JavaScript,但几乎无法理解:

alert(a); // Where does a come from? Why does this not throw?
/* 1000 lines later, or even in an entirely different file */
var a;

此外,想象一下代码有 5 个 var 声明,用于同一范围内的同一个变量,一些在 if 语句中,一些在 fors 中。哪个是第一?最终会创造什么价值?

这个想法是修复一些 bad parts of var

【讨论】:

    【解决方案2】:

    任何严格的运算符出现在任何编程语言中的原因都是一样的——限制你可以在脚上开枪的方式的数量。老式 Javascript 充满了这些。

    请注意,您可以将let 用于块本地范围:

    while (i < 5)
    {
      let a = 42;
    
      i++;
    }
    

    即使循环运行了几次,a 总是被正确初始化。

    现在,如果您在更高范围内有另一个变量会发生什么?

    let a = 42;
    
    while (i < 5)
    {
      let a = 10;
    
      // What is the value of a here?
      i++;
    }
    
    // And here?
    

    这里存在一定程度的歧义 - 歧义是编程语言中的一个坏特性。这对于非块范围的var 来说不是问题——它有很多自己的问题,人们一直在滥用它,但至少很明显var从不 em> 块作用域。即便如此 - 人们确实使用它,就好像它块范围的。

    解决这种精神错乱的唯一方法是使语言更严格一些。这实际上是否意味着您失去了任何功能?不,变量阴影对var 来说是个坏主意,对let 来说仍然是个坏主意(正如我的示例所示,可能更糟)。

    这不是 Javascript 独有的,绝对不是。例如,在 C# 中:

    int i = 0;
    
    int i = 42; // Compiler error: A local variable named 'i' is already defined in this scope
    

    为什么?因为您显然犯了一个错误。也许您从其他地方复制了一段代码,但没有注意到您已经声明了另一个名为i 的变量。也许您忘记了您正处于另一个循环的中间,该循环也使用i 作为循环变量。没有真正的合法用途,但有大量的失败模式——这只是一个糟糕的语言特性。简单的编译器错误阻止了几乎所有这些故障的发生——而且其中许多故障很难找到,尤其是在“内部”块不经常使用的情况下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-12
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-26
      • 2013-02-23
      • 1970-01-01
      • 2019-01-20
      相关资源
      最近更新 更多