我一直在查看Mozilla 开发人员网络上的 JavaScript 参考,我遇到了一个叫做"strict mode"
. 我读了一遍,但无法理解它的作用。有人可以简要解释(一般而言)它的目的是什么以及它是如何有用的?
什么是“严格模式”,它是如何使用的?
它的主要目的是做更多的检查。
只需"use strict";
在代码顶部添加,然后再添加其他任何内容。
例如,blah = 33;
是有效的 JavaScript。这意味着您创建了一个完全全局变量blah
。
但是在严格模式下这是一个错误,因为您没有使用关键字“var”来声明变量。
大多数情况下,您并不是要在某个任意范围的中间创建全局变量,因此大多数情况下blah = 33
编写它是一个错误,程序员实际上并不希望它成为全局变量,他们的意思是写var blah = 33
。
它同样不允许许多技术上有效的事情去做。NaN = "lol"
不会产生错误。它也不会改变 NaN 的值。使用严格的 this(和类似的奇怪的语句)会产生错误。大多数人欣赏这一点,因为没有理由写NaN = "lol"
,所以很可能是错字。
Simon 的回答中没有提到的严格模式的一个方面是严格模式设置this
为undefined
通过函数调用调用的函数。
所以像这样的事情
function Obj() {
this.a = 12;
this.b = "a";
this.privilegedMethod = function () {
this.a++;
privateMethod();
};
function privateMethod() {
this.b = "foo";
}
}
privateMethod
调用时会导致错误(因为您无法向 中添加属性undefined
),而不是无用地向b
全局对象添加属性。
添加了严格模式,以便有一个易于静态分析的ECMAScript子集,这将是该语言未来版本的良好目标。严格模式的设计也是希望将自己限制在严格模式的开发人员犯的错误更少,并且他们所犯的错误会以更明显的方式表现出来。
Harmony有望成为 ECMAScript 的下一个主要版本,它将建立在 ES5 strict 之上。
Harmony 建立在 ES5 严格模式之上,以避免模式过多。
其他一些语言实验也依赖于严格模式。SES依赖于 ES5 严格模式的可分析性。
SES (Secure ECMAScript) 设计实验
通过删除或修复 ES5/Strict 中的功能来设计对象能力编程语言。
应该有从 SES 到 ES5/Strict 的直接转换。
标准的附录 C解释了严格模式和正常模式之间的区别。
严格模式限制和例外
- 标识符“implements”、“interface”、“let”、“package”、“private”、“protected”、“public”、“static”和“yield”在严格模式代码中被归类为 FutureReservedWord 标记。(7.6.12 [?])。
- 在处理严格模式代码时,符合要求的实现可能不会扩展 NumericLiteral (7.8.3) 的语法以包含如 B.1.1 中所述的 OctalIntegerLiteral。
- 在处理严格模式代码(见 10.1.1)时,一个符合要求的实现可能不会扩展 EscapeSequence 的语法以包含如 B.1.2 中描述的 OctalEscapeSequence。
- 分配给未声明的标识符或其他无法解析的引用不会在全局对象中创建属性。当在严格模式代码中发生简单赋值时,其 LeftHandSide 不得评估为无法解析的引用。如果确实如此,则会引发 ReferenceError 异常(8.7.2)。LeftHandSide 也可能不是对属性值为 {[[Writable]]:false} 的数据属性的引用、对属性值为 {[[Set]]:undefined} 的访问器属性的引用,也可能不是对不存在的引用[[Extensible]] 内部属性值为 false 的对象的属性。在这些情况下,会抛出 TypeError 异常 (11.13.1)。
- 标识符 eval 或参数不能作为赋值运算符 (11.13) 或 PostfixExpression (11.3) 的 LeftHandSideExpression 或作为由前缀增量 (11.4.4) 或前缀减量 (11.4.5) 运算符操作的一元表达式出现. 严格模式函数的参数对象定义了名为“caller”和“callee”的不可配置的访问器属性,它们在访问时抛出 TypeError 异常 (10.6)。
- 严格模式函数的参数对象不会与其函数的相应形式参数绑定动态共享其数组索引属性值。(10.6)。对于严格模式函数,如果创建了参数对象,则本地标识符参数与参数对象的绑定是不可变的,因此可能不是赋值表达式的目标。(10.5)。
- 如果严格模式代码包含具有多个数据属性定义的 ObjectLiteral (11.1.5),则为 SyntaxError。如果标识符“eval”或标识符“arguments”作为包含在严格代码中的 PropertyAssignment 的 PropertySetParameterList 中的标识符出现,或者它的 FunctionBody 是严格代码 (11.1.5),则它是 SyntaxError。
- 严格模式 eval 代码不能实例化调用者变量环境中的变量或函数来进行 eval。相反,会创建一个新的变量环境,并且该环境用于 eval 代码 (10.4.2) 的声明绑定实例化。
- 如果在严格模式代码中计算 this,则 this 值不会被强制转换为对象。null 或 undefined 的 this 值不会转换为全局对象,并且原始值不会转换为包装器对象。通过函数调用(包括使用 Function.prototype.apply 和 Function.prototype.call 进行的调用)传递的 this 值不会强制将传递的 this 值传递给对象 (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4)。
- 当删除运算符出现在严格模式代码中时,如果其 UnaryExpression 是对变量、函数参数或函数名称 (11.4.1) 的直接引用,则会引发 SyntaxError。
- 当删除操作符出现在严格模式代码中时,如果要删除的属性具有属性 { [[Configurable]]:false } (11.4.1),则会抛出 TypeError。如果 VariableDeclaration 或 VariableDeclarationNoIn 出现在严格代码中并且其标识符为 eval 或 arguments (12.2.1),则为 SyntaxError。
- 严格模式代码可能不包含 WithStatement。在这样的上下文中出现 WithStatement 是 SyntaxError (12.10)。
- 如果在严格的代码中出现带有 Catch 的 TryStatement 并且 Catch 产生式的标识符是 eval 或 arguments (12.14.1),则它是 SyntaxError
- 如果标识符 eval 或 arguments 出现在严格模式 FunctionDeclaration 或 FunctionExpression (13.1) 的 FormalParameterList 中,则为 SyntaxError
- 严格模式函数不能有两个或多个同名的形参。尝试使用 FunctionDeclaration、FunctionExpression 或 Function 构造函数创建这样的函数是 SyntaxError (13.1, 15.3.2)。
- 除了本规范中定义的之外,实现不能扩展在名为 caller 的属性或函数实例的参数的严格模式函数中的含义。ECMAScript 代码不得在与严格模式函数(10.6、13.2、15.3.4.5.3)对应的函数对象上创建或修改具有这些名称的属性。
- 在严格模式代码中使用标识符 eval 或 arguments 作为 FunctionDeclaration 或 FunctionExpression 的标识符或作为形式参数名称 (13.1) 是 SyntaxError 。尝试使用 Function 构造函数 (15.3.2) 动态定义这样的严格模式函数将引发 SyntaxError 异常。
ECMAScript 5 引入了严格模式的概念。
在代码中调用严格模式
严格模式适用于整个脚本或单个函数。它不适用于括在 {} 大括号中的块语句,尝试将其应用于此类上下文没有任何作用。
整个脚本:
假设我们正在创建 app.js,因此添加第一条语句 use script 将对整个代码强制执行严格模式。
// app.js whole script in strict mode syntax
“use strict”;
// Now you can start writing your code
函数的严格模式:
要为函数调用严格模式,请使用确切的语句“use strict”;在任何其他语句之前的函数体的开头。
function yourFunc(){
"use strict";
// Your function code logic
}
严格模式包含对普通 JavaScript 语义的一些更改。首先,严格模式通过将一些 JavaScript 静默错误更改为抛出错误来消除它们。
例如:使用严格模式的代码
在上面的代码示例中,在代码中不使用严格模式是不会抛出错误的。因为我们正在访问变量x
而不声明它。所以在严格模式下访问未声明的变量会引发错误。
现在让我们尝试访问一个变量 x,而不在没有严格模式的情况下声明它。
(function(){
x = 3;
})();
// Will not throw an error
使用严格模式的优点:
- 通过抛出错误来消除 JavaScript 静默错误。
- 修复了导致 JavaScript 引擎难以执行优化的错误。
- 使代码有时比非严格模式的相同代码运行得更快
- 禁止某些可能在 ECMAScript 未来版本中定义的语法。
严格模式对正常的 JavaScript 语义进行了一些更改。
严格模式通过将一些 JavaScript 静默错误更改为抛出错误来消除它们。
严格模式修复了使 JavaScript 引擎难以执行优化的错误。
严格模式禁止某些可能在 ECMAScript 未来版本中定义的语法。