ECMAScript 5的严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码显示地 脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式。
严格模式不仅仅是一个子集:它的产生是为了形成与正常代码不同的语义。
不支持严格模式与支持严格模式的浏览器在执行严格模式代码时会采用不同行为。
所以在没有对运行环境展开特性测试来验证对于严格模式相关方面支持的情况下,就算采用了严格模式也不一定会取得预期效果。严格模式代码和非严格模式代码可以共存,因此项目脚本可以渐进式地采用严格模式。
严格模式对正常的 JavaScript语义做了一些更改。
严格模式通过抛出错误来消除了一些原有静默错误。
严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
如何开启严格模式
【脚本开启】
在所有js代码之前,添加'use strict';
但全局开启严格模式后,就不能盲目进行冲突合并。在皆为严格模式时是相安无事的,但如若一个为严格模式一个为非严格模式,就会引起问题。
【函数内开启】
在函数头部,添加'use strict';
严格模式中的变化
将过失错误转为异常
【导致静默失败的赋值操作异常】
"use strict";
// 给不可写属性赋值
var obj = {}
Object.defineProperty(obj, 'x', {value: 1, writable: false})
obj.x = 2 // throw Error
// 修改只读属性
var obj = {
get x(){
return 7;
}
}
obj.x = 10; // throw Error
// 给不可扩展的对象设置新属性
var fixed = {}
Object.preventExtensions(fixed)
fixed.newProps = 1 // throw Error
【无法再意外创建全局属性】
在非严格模式下,当写错全局属性名时,不会报错,而是隐式创建了另一个全局属性,进行操作。
"use strict";
// 假定某全局变量名为 globalName
globelName = 'ashen'; // throw Error
【删除不能删除的属性时报出异常】
在非严格模式下,不会有任何反应
"use strict";
delete Object.property // throw Error
【要求函数的参数名唯一】
在非严格模式下,调用时,重名的后者会覆盖前者。但直接使用arguments[i]还是可以访问前面的属性
"use strict";
function(a, a, b){
return a + a + b // throw Error
}
【不能设置原始类型的值的属性】
在非严格模式下,会简单忽略
"use strict";
"hello".world = "hello world"; // throw Error
简化变量的使用
【不能使用with】
在非严格模式下,with语句中的this,指向传入的参数,还是全局对象,要等到运行时才能决定
【eval()不再为上层范围,引入新变量】
一般情况下, 在一个包含 eval 调用的函数内所有没有引用到参数或者局部变量的名称都必须在运行时才能被映射到特定的定义 (因为 eval 可能引入的新变量会覆盖它的外层变量). 在严格模式下 eval 仅仅为被运行的代码创建变量, 所以 eval 不会使得名称映射到外部变量或者其他局部变量
【禁止删除声明变量】
"use strict";
var x;
delete x;
使eval和arguments变得简单
【eval和arguments不可被绑定和赋值】
【arguments不会随着传入参数的变化而变化】
"use strict";
function f(a){
a = 50;
return [a, arguments[0]];
}
f(20); // 返回值为[50, 20]
【arguments.callee不可使用】
"安全的" JavaScript
【通过this传递给一个函数的值不会被强制转换为一个对象】
如果没有指定this,将为undefined
"use strict";
function test(){return this;}
test(a) // 返回a
test() // 返回undefined
为未来的ECMAScript版本铺平道路
【一部分字符变成了保留的关键字】
这些字符包括implements, interface, let, package, private, protected, public, static和yield。在严格模式下,你不能再用这些名字作为变量名或者形参名。
【禁止了不在脚本或者函数层面上的函数声明】
参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode