严格模式主要有以下几方面的作用及内容:
一、对作用域的限制:
- 使用未经声明的变量,报错(防止变量作用域提升);
- eval语句内声明的变量,作用域限制在eval之内(非严格模式时,eval语句内变量的作用域与eval所在作用域一致);
二、防止性能问题
动态作用域无法使用编译阶段-词法分析已经确定的作用域,影响性能,因此
- 禁止使用with语句;
- 禁止使用argument.callee;
三、禁止使用非es标准、已废弃的语法
- 禁止使用Function.caller,因为不是es规范;
- 禁止使用Function.argument,因为已经从web标准中删除
- 禁止在整数前面加0表示8进制(含\0这种转义表示),因为这不是es规范,而是浏览器不成俗的约定(在es6中定义了8进制的表示法,使用0o)
- 禁止使用arguments作为变量名
- 禁止this指向全局对象(让人产生困惑,不符合常规思维)
Foo.method = function() { function test() { // 常规情况下,this 将会被设置为全局对象,也就是 window 对象 } test(); }
四、安全性相关
- 禁止删除变量、函数、对象;
- 禁止重名:函数的参数,对象的属性;
- 对象字面量进行不允许的操作时,直接报错,而不是静默失败。这些操作包括:
- 对只读属性赋值(Object.definePropery里使用了writeable描述器,或一个属性只有get而没有set)
- 删除一个不允许删除的对象时(Object.defineProperty中configurable为false或使用Object.seal、Object.freeze)
- 对禁止添加属性的对象(使用Object.preventExtensions、Object.seal、Object.freeze)增加新的属性
- arguments自动更新功能不可用,正常情况下:
function foo(a, b, c) { arguments[0] = 2; a; // 2 b = 4; arguments[1]; // 4 var d = c; d = 9; c; // 3 } foo(1, 2, 3);
五、禁止使用保留的关键字,为未来升级做准备
package implements interface,public private protected,let、static、yield