ES5最先引入了严格模式的概念。经过严格模式,能够在函数内部选择较为严格的全局或局部的错误条件检测。使用严格模式的好处是,能够提前地发现函数内部存在的错误以及编译中产生的错误。 支持严格模式的浏览器包括IE10+、FireFox4+、Safari5.1+和Chrome。javascript
使用编译指示,实际上就是一个字符串:"use strict";
若是在全局做用域中(函数外部)使用这个编译指示,则整个脚本都将使用严格模式。 也就是说,若是把带有严格模式的脚本放在其余文件中,那么这个文件下的JS代码也会处于严格模式下。 也能够在函数中打开严格模式,java
function fn() {
"use strict";
// more codes
}
复制代码
在严格模式下,何时建立变量以及怎么建立变量都是有限制的。浏览器
不容许意外建立全局变量,必需要有一个声明。app
var msg = "Hello!";
复制代码
不能对变量调用delete操做符。在非严格模式下会静默失败,可是不会报错。而在严格模式下会报错。函数
严格模式下,不能使用implements、interface、let、package、private、protected、public、static、yield等保留字做为变量名。ui
在非严格模式下,操做对象时有些错误会静默失败,而在严格模式下就会报错。 如下状况时操做对象会报错:this
另外严格模式下,在经过对象字面量形式来声明对象时,属性名必须惟一,不然会报错。spa
var person = {
name: 'Knight',
name: 'Bill'
} // Error
复制代码
function add(a, a) {
// dosomething
}
复制代码
解析: 上面这段函数声明在非严格模式下是不会报错的。 严格模式下,经过参数名只能访问第二个参数,第一个参数必须经过**arguments对象(形参列表)**进行访问。code
在严格模式下,arguments对象的行为和非严格模式是有区别的。 在非严格模式下,修改命名参数的值会反映到arguments对象中,可是在严格模式下这两个值是相互独立的。cdn
function showName(name) {
name = 'Mike',
console.log(name); // 'Mike'
console.log(arguments[0]); // 非严格模式:'Mike'; 严格模式: 'Bill'
}
showName('Bill');
复制代码
解析:在调用函数时,首先会传入实参值'Bill',并写入arguments对象中。 在非严格模式下,函数内部将name值从新赋值为'Mike',所以arguments[0]的值也被同时修改成'Mike'。 而在严格模式下,arguments[0]的值依然是'Bill'。
在非严格模式下,这两个属性一个引用函数自己,一个引用调用函数。 而在严格模式下,这两个属性被淘汰,使用时均会报错。
// 求一个阶乘
function fn(num) {
if(num <= 1) {
return 1;
}else {
return num * arguments.callee(num-1);
}
}
console.log(fn(3)); // 3! = 6
复制代码
解析: 这是一个求阶乘的函数,在非严格模式下,调用函数时,可用arguments.callee()来调用函数自己,从而实现函数功能。 而在严格模式下则会报错。
严格模式下,不能使用implements、interface、let、package、private、protected、public、static、yield等保留字做为函数变量名。
在严格模式下,只能在脚本的顶级和在函数内部声明函数。也就是说,在if语句/for语句中,声明函数是会报错的。
"use strict";
if (true) {
function f() { } // !!! 语法错误
f();
}
for (var i = 0; i < 5; i++) {
function f2() { } // !!! 语法错误
f2();
}
function baz() { // 合法
function eit() { } // 一样合法
}
复制代码
eval()在包含上下文中再也不建立变量和函数。
function fn() {
eval("var x = 123;");
console.log(x);
}
fn();
复制代码
解析:上述代码在严格模式下是会报错的(ReferenceError),而在非严格模式下正常运行。
严格模式不容许使用eval和arguments做为标识符,也不容许读写它们的值。
var eval = 'hello';
var arguments = 'world';
复制代码
解析:这在非严格模式下是能够解析运行的,可是在严格模式下会报错。 所以,不能将它们用做标识符,如下几种状况均会抛出语法错误:
在非严格模式下使用apply()或者call()方法时,null和undefined值会转换为全局对象。 而在严格模式下,函数的this值始终是指定的值,不管指定的是什么值。
var color = "red";
function displayColor() {
console.log(this.color);
}
displayColor.call(null);
复制代码
解析: 在非严格模式下,displayColor.call()中传入了null,那么此时函数的this是全局对象,所以会打印出red。 而在严格模式下,这个函数的this就是null,所以在访问null的属性时会报错。
非严格模式下,with语句能够改变解析标识符的路径,可是在严格模式下,with被简化,会报错。
with(location) {
alert(href);
}
复制代码
以0开头的八进制字面量过去常常会致使不少错误。 所以,在严格模式下,八进制字面量已经被抛弃。
var val = 010;
复制代码
在ES5标准的严格模式下,八进制字面量会被当作以0开头的十进制字面量。
var val = parseInt("010");
console.log(val); // 10
复制代码