JavaScript的严格模式对隐式全局声明到底有什么作用?

时间:2018-12-20 20:28:21

标签: javascript strict

来自MDN article about strict mode

  

首先,严格模式使得不可能意外创建全局   变量。在普通的JavaScript中,迷惑分配中的变量   在全局对象上创建一个新属性,然后继续“工作”   (尽管将来可能会失败:很可能在现代JavaScript中)。   分配,这会意外地创建全局变量   在严格模式下引发错误:

'use strict';
                       // Assuming a global variable mistypedVariable exists
mistypeVariable = 17;  // this line throws a ReferenceError due to the 
                       // misspelling of variable

这是什么意思? 引擎是否检测到名称相似的变量是否已经存在(?!),还是严格模式仅禁止声明超出全局范围的全局变量?

以上引用似乎暗示了第一种可能性,但这似乎...很奇怪?

3 个答案:

答案 0 :(得分:3)

引用的代码中的注释具有误导性:“假定”部分无关紧要。它应该真正显示为:“假设没有具有完全的全局变量,该名称是用letvar定义的,... “

但是请注意代码片段和注释的目的是:为了表明在严格模式下发现拼写错误要容易得多。在草率模式下,拼写错误将不被注意(没有错误),并且您将使用两个变量而不知道它(至少一段时间)

答案 1 :(得分:3)

根据要求,我将其答复:)

我认为您已经了解了这里发生的事情,并且通过阅读有关“假设全局变量...”的引用而从字面上也感到困惑。 (我承认它的表述方式可能会导致这种混乱。)实际情况非常简单,与具有“相似名称”(JS没有概念)的变量无关: / p>

正在讨论的是,如果您给尚未正式声明的变量赋值(使用变量varlet或{{1}中的一个声明变量),会发生什么情况。 }。不声明变量是不好的做法,在严格模式下会引发错误-这是一件好事,并警告您错误。但是在非严格模式下,JS会很乐意接受这一点,并认为您想声明该名称的 global 变量。这几乎永远不是您真正想要的,因为它会污染全局名称空间,不会通知您错误,并且以后可能会导致各种棘手的错误。

答案 2 :(得分:0)

  

严格模式是否仅禁止声明超出全局范围的全局变量?

严格模式绝对不禁止在任何地方声明全局变量。在非严格模式下,如果您输入:

someVar = 't';

它将评估为:

window.someVar = 't';

why is this happening?)尽管在函数范围之内或之外进行编写。实际上,该行既是变量的声明,也是变量的评估(再看一遍,它没有var,因此它不应该声明任何东西!)。

但是这会导致这种副作用,效果并不完全良好,他们引入了strict-mode,当激活时,我们的第一行将抛出错误。因为它只是评估而无需先声明。

现在,如果您需要在函数作用域内操作全局作用域,则只应将全局对象作为参考:

var someGlobalVar;
var someOtherGlobalVar;

function hello() {

    // this will make *someGlobalVar* to be redefined in the inner scope
    // someGlobalVar != window.someGlobalVar
    var someGlobalVar;

    // manipulating inner variable, not global one
    someGlobalVar = 's';


    // it's fine, you've accessed global object correctly
    window.someGlobalVar = 's';


    // you're still editing global object, because
    // there's no other variable inside of this scope having the same name
    someOtherGlobalVar = 's';

}