ES5新特性——严格模式
目的
- 消除语法不合理、不严谨
- 消除运行不安全
- 提高速度 ?
- 新版本模块化做铺垫
语法
"use strict"//是一个指令,指示解释器用更严格的方式检查代码
如何调用
- 针对整个脚本文件:放在脚本文件的第一行
<script>
"use strict"
a = 3
console.log(a) //报错
</script>
<script>
b = 4
console.log(b) //4
</script>
- 针对单个函数:放在函数体的第一行
- 脚本文件变通写法:将整个脚本文件放在一个立即执行的匿名函数中
限制
- 全局变量
- 变量必须声明后再使用
- 属性和方法在编译阶段就能确定属于那个对象;有利于编译效率的提高。
- 禁止使用with语句 ; 因为with无法在编译时就确定属性到底归属于哪个对象
- 创设eval作用域;不能生成全局变量,他所生成的变量只能用于eval内部
//with
var o = {name:'张三'}
with (o){
console.log(name)
}
//eval
var code = "var a = 3;console.log(a)"
eval(code)
- 增强的安全措施
- 禁止使用this关键字指向全局对象
function f() {
"use strict";
this.a = 1;
}
f(); // 报错,this未定义
var f1 = new f();
console.log(f1.a);
- 禁止在函数内部遍历调用栈
function f() {
"use strict";
f1.caller; // 报错
f1.arguments; // 报错
}
- 禁止删除变量:只有configurable设置为true的对象属性,才能被删除
"use strict";
var x;
delete x; // 语法错误
var o = Object.create(null, {'x': {
value: 1,
configurable: true
}});
delete o.x; // 删除成功
- 显性报错
- 正常模式下,对一个对象的只读属性进行赋值,不会报错,只会默默地失败。严格模式下,将报错
"use strict";
var o = {};
Object.defineProperty(o, "v", { value: 1, writable: false });
o.v = 2; // 报错
- 严格模式下,对一个使用getter方法读取的属性进行赋值,会报错
"use strict";
var o = {
get v() { return 1; }
};
o.v = 2; // 报错
- 严格模式下,对禁止扩展的对象添加新属性,会报错
"use strict";
var o = {};
Object.preventExtensions(o);
o.v = 1; // 报错
- 严格模式下,删除一个不可删除的属性,会报错
"use strict";
delete Object.prototype; // 报错
- 重名错误:
- 对象不能有重名的属性:正常模式下最后赋值的属性会覆盖前面的值,严格模式下属于语法错误;
- 函数不能有重名的参数;
- 禁止八进制表示法:
- 正常模式下,整数的第一位如果是0,表示这是八进制数,比如 0100 等于10进制的64。严格模式下禁止这种表示法,将报错。
- arguments对象的限制
- 不允许对arguments赋值;
- arguments不再追踪参数的变化;
- 禁止使用arguments.callee:意味这无法在匿名函数内部调用自身了。
- 函数必须生命在顶层
- 严格模式只允许在全局作用域或函数作用域的顶层声明函数。也就是说,不允许在非函数的代码块内声明函数。
"use strict";
if (true) {
function f() { } // 语法错误
}
for (var i = 0; i < 5; i++) {
function f2() { } // 语法错误
}
- 保留字
- 严格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。使用这些词作为变量名将会报错;
参考网址: 阮一峰严格模式详解