来自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
这是什么意思? 引擎是否检测到名称相似的变量是否已经存在(?!),还是严格模式仅禁止声明超出全局范围的全局变量?
以上引用似乎暗示了第一种可能性,但这似乎...很奇怪?
答案 0 :(得分:3)
引用的代码中的注释具有误导性:“假定”部分无关紧要。它应该真正显示为:“假设没有具有完全的全局变量,该名称是用let
或var
定义的,... “
但是请注意代码片段和注释的目的是:为了表明在严格模式下发现拼写错误要容易得多。在草率模式下,拼写错误将不被注意(没有错误),并且您将使用两个变量而不知道它(至少一段时间)
答案 1 :(得分:3)
根据要求,我将其答复:)
我认为您已经了解了这里发生的事情,并且通过阅读有关“假设全局变量...”的引用而从字面上也感到困惑。 (我承认它的表述方式可能会导致这种混乱。)实际情况非常简单,与具有“相似名称”(JS没有概念)的变量无关: / p>
正在讨论的是,如果您给尚未正式声明的变量赋值(使用变量var
,let
或{{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';
}