为什么让语句的行为与var有很大不同?

时间:2015-10-21 07:16:06

标签: javascript ecmascript-6

我知道<reference name="left"> <block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml"/> </reference> 是声明块范围局部变量,但为什么它不支持重新声明和像let那样的提升?

此限制的设计目的是什么?

var

2 个答案:

答案 0 :(得分:8)

我们的想法是创建一个比原始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语句中,有些在for s中。哪个是第一个?最终会创造什么价值?

我们的想法是修复一些 bad parts of var

答案 1 :(得分:1)

任何编程语言中出现任何严格操作符的原因相同 - 限制你可以用脚射击自己的方式。老派的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永远块范围。即便如此 - 人们也会像使用 块范围一样使用它。

解决这种疯狂的唯一方法是使语言更加严格。这真的意味着你失去了任何功能吗?不可变。使用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作为循环变量。没有真正的合法用途,但是有大量的失败模式 - 这只是一种糟糕的语言特征。简单的编译器错误可以防止几乎所有这些失败发生 - 并且很多失败很难找到,特别是如果不经常使用“内部”块。