严格模式是Javascript中的一种限制性更强的変种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。
不支持严格模式的刘览器与支持严格模式的浏览器行为上也不一样,所以不要在未经严格模式特性测试情况下使用严格模式。
严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。
首先,严格模式会将Javascript陷阱直接变成明显的错误。
其次,严格模式修正了一些引擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快
第三,严格模式禁用了一些有可能在未来版本中定义的语法。
只需要在全局写以下字符串即可。作用于全局作用域
"use strict";
a = 100;
console.log(a);
在函数内写以下字符串即可。只作用于函数作用域。例如:
function fn() {
"use strict";
v = 200;
console.log(v);
}
所谓静默失败就是既不报错也没有任何效果,例如改变常量的值。在严格模式下,静默失败会转换成抛出异常。
例如:
// 定义一个常量
const v = 3.14;
// 重新赋值
v = 1.14;
console.log(v);
以上代码在稍微老一点的浏览器可能并不会报错(新版报错),但开启严格模式后,一定会报错。
在严格模式下不能对变量使用delete
运算符。
例如:
var v = 100;
console.log(v); //100
delete v;
console.log(v); //100
严格模式下禁用delete只针对删除变量,而不是数组元素和对象属性。
"use strict";
var arr = [0, 1, 2, 3, 4];
delete arr[0];
console.log(arr); //[ <1 empty item>, 1, 2, 3, 4 ]
var obj = {
name: "张无忌",
};
delete obj.name;
console.log(obj.name); // undefined
在严格模式下,JavaScript对变量名也有限制。特别不能使用如下内容作为变量名:
implements
interface
let
package
private
protected
public
static
yield
上述关键词表示在ECMAScript的下一个版本中可能会用到他们,在严格模式下使用以上字符作为变量名会导致语法错误。
"use strict";
delete Object.prototype;
console.log(Object.prototype);
// 报错
非严格模式下不会报错,但也不会删除成功。但在严格模式下会直接抛出错误。
但严格模式并不会限制所有对象,例如:
"use strict";
delete Math.random;
console.log(Math.random); //undefined
Math.random();
即使在严格模式下,还是可以删除Math.random
方法。
在严格模式下,一个对象内的所有属性名在对象内必须唯一。
"use strict";
var obj = {
name: "张无忌",
name: "周芷若",
};
console.log(obj.name); // 周芷若
开启严格模式后,如果对象具有相同属性,那么并不会报错,而是覆盖。
"use strict";
var obj = {};
Object.defineProperty(obj, "age", {
value: 18,
});
// 针对只读属性进行修改操作
obj.age = 80;
console.log(obj.age);
delete obj.age;
console.log(obj.age);
对于不可修改的属性,无论是修改还是删除都会发生报错。
在严格模式下,不能为不可扩展的对象添加新属性。
"use strict";
var obj = {};
// 设置对象obj是一个不可扩展的对象
Object.preventExtensions(obj);
// 为对象obj新增属性或方法
obj.name = "张无忌";
console.log(obj);
以上代码在严格模式下会报错,非严格模式下不会报错。
在严格模式下,要求命名函数的参数必须唯一。
function fn(a, a, b) {
console.log(a + a + b);
}
fn(1, 2, 3); //7
例如以上代码,非严格模式下会输出7,两个参数a都会被当作2;但在严格模式下,会抛出错误。
在严格模式下, arguments对象的行为也有所不同。
"use strict";
function fn(value) {
var value = "张无忌";
console.log(value); // 张无忌
console.log(arguments[0]); //严格模式下为周芷若 非严格模式下为周芷若
}
fn("周芷若");
非严格模式下arguments对象获取参数的值与形参有关。(如果局部变量与形参名相同,则根据就近原则获取);严格模式下arguments对象获取参数的值与形参无关。
在严格模式下,不能使用armaments对象的callee()方法。
"use strict";
function fn() {
return arguments.callee;
}
fn();
以上代码在严格模式下会直接报错。
在严格模式下,只能在全局域和函数域中声明函数。
"use strict";
// 在全局作用域
function fn() {
function n() {}
}
for (var i = 0; i < 10; i++) {
// ECMAscript 6 新增 - 存在块级作用域
var v = 100;
// 开启严格模式后在块级不能定义函数
function f() {
console.log("this is function");
}
}
console.log(v); // 100
f(); // ReferenceError: f is not defined
在严格模式下,函数的定义只能在全局作用域与函数作用域,不能在块级作用域
在严格模式下,使用eval()
函数创建的变量只能在eval()
函数内部使用。
eval("var v = 100");
console.log(v);
以上代码在非严格模式下会输出100
,而在严格模式下会抛出错误。
在严格模式下,会增加eval作用域。也就是说在eval函数定义的变量只能在当前eval函数使用。
在严格模式下,禁止使用eval()和arguments作为标示符,也不允许读写它们的值。
以下语句在严格模式下均会报错:
eval = 17;
arguments++;
++eval;
var obj = {
set p(arguments) {},
};
var eval;
try {
} catch (arguments) {}
function x(eval) {}
function (eval) { }
function arguments() { }
var y = function eval() { }
var f = new Function('arguments', "'use strict';return 17;")
apyly()
或call()
方法时,null
或undefined
值会被转换为全局对象。this
值始终是指定的值(无论什么值)。"use strict";
var v = 100;
function fn() {
console.log(this.v);
}
var obj = {
v: 200,
};
fn.call(null);
在严格模式下会抛出错误,必须明确指定this,例如fn.call(obj);
。