严格模式
概述
严格模式是什么
严格模式是 JavaScript 中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。
不支持严格模式的浏览器与支持严格模式的浏览器行为上也不一样,所以不要 在未经严格模式特性测试情况下使用严格模式。
严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。
严格模式的目的
-
严格模式会将 JavaScript 陷阱直接变成明显的错误。
-
严格模式修正了一些引|擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快。
-
严格模式禁用了一些有可能在未来版本中定义的语法。
开启严格模式
全部开启严格模式
在 JavaScript 中想要开启严格模式,需要在所有代码之前,定义一个不会赋给任何变量的字符串:
"use strict"; // 或者 'use strict';
如果之前的 JavaScript 代码是非严格模式的话,建议不要盲目为这段代码开启严格模式,这样可能会出现问题。建议按一个个函数去开启严格模式(至少在学习过程的过渡期要这样做)。
函数开启严格模式
也可以为某个指定的函数开启严格模式,如下代码示例:
// 函数外依旧是非严格模式
function doSomething(){
"use strict"; // 开启严格模式
// 其他代码
}
在匿名函数中使用严格模式,相当于在全局开启严格模式的变通实现方式。
(function(){
"use strict"; // 开启严格模式
})();
变量
禁止意外创建变量
在严格模式下,不允许意外创建全局变量。
- 如下代码是非严格模式下意外创建全局变量。
// 未声明变量
message = "this is message";
- 如下代码是严格模式下意外创建全局变量。
"use strict"; // 开启严格模式
// 严格模式下,意外创建全局变量,抛出 ReferenceError
message = "this is message";
静默失败转化为异常
所谓静默失败就是既不保持也没有任何效果,例如,改变常量的值。在严格模式下,静默失败会转换成抛出异常。
- 如下代码是非严格模式下的静默失败
const A = 3.14;
A = 1.14; // 静默失败
console.log(A); // 3.14
- 如下代码是严格模式下的静默失败
"use strict"; // 开启严格模式
const A = 3.14
A = 1.14; // 抛出 TypeError 错误
禁用 delete 关键字
在严格模式下,不能对变量使用 delete
运算符。
- 如下代码是非严格模式下使用
delete
运算符,结果会静默失败。
var color = "red";
delete color;
- 如下代码是严格模式下使用
delete
运算符,结果会抛出异常。
"use strict"; // 开启严格模式
var color = "red";
delete color; // 抛出 ReferenceError 错误
对变量名的限制
在严格模式下,JavaScript 对变量名也有限制。特别不能使用如下内容作为变量名:
implement | interface | let | package |
---|---|---|---|
private | protected | public | static |
yield |
上述内容都是保留字,在 ECMAScript 的下一个版本中可能会用到它们。
在严格模式下,使用上述标识符作为变量名会导致语法错误。
对象
不可删除的属性
在严格模式下,不能使用 delete
运算符删除不可删除的属性。
- 如下代码是非严格模式下使用
delete
运算符删除不可删除的属性,结果会静默失败。
delete Object.prototype;
- 如下代码是严格模式下使用
delete
运算符删除不可删除的属性,结果会抛出异常。
"use strict"; // 开启严格模式
delete Object.prototype; // 抛出 TypeError 错误
属性名必须唯一
在严格模式下,一个对象内的所有属性名在对象内必须唯一。
- 如下代码是非严格模式下重名函数的属性觉得其属性值。
var o={p:1,p=2};
- 如下代码是严格模式下重命名属性被认为是语法错误
"use strict"; // 开启严格模式
var o = {p:1,p:2}; // !!! 语法错误
只读属性的赋值
在严格模式下,不能为一个只读的属性进行重新赋值。
- 如下代码是非严格模式为只读属性重新赋值,结果会静默失败。
var obj1 = {};
Object.defineProperty(obj,"X",{value:42,writble: false}); // 将属性设为已读
obj1.x = 9;
- 如下代码是严格模式下为只读属性重新赋值,结果会抛出异常。
"use strict"; //开启严格模式
var.obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false }); //将属性设置为只读
obj1.x= 9; //抛出TypeError错误