23严格模式
概述
严格模式是什么
严格模式是Javascript中的一种限制性更强的変种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。
不支持严格模式的刘览器与支持严格模式的浏览器行为上也不一样,所以不要在未经严格模式特性测试情况下使用严格模式。
严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。
严格模式的目的
首先,严格模式会将Javascript陷阱直接变成明显的错误。
其次,严格模式修正了一些引擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快
第三,严格模式禁用了一些有可能在未来版本中定义的语法。
开启严格模式
全局开启严格模式
只需要在全局写以下字符串即可。作用于全局作用域
1 | ; |
函数开启严格模式
在函数内写以下字符串即可。只作用于函数作用域。例如:
1 | function fn() { |
变量
禁止意外创建变量
非严格模式
在函数作用域中定义变量,不适用var关键字那么自动将其提升为全局变量。例如:
1
2
3
4
5
6function fn() {
w = 200;
console.log(w); //200
}
fn();
console.log(w); //200严格模式下
在严格模式下则会抛出异常
1
2
3
4
5
6
7
8
9
10
11;
function fn() {
// 在函数作用域中定义变量 - 不适用var关键字-> 自动将其提升为全局变量
w = 200;
console.log(w);
}
fn();
console.log(w);
// v = 100;
// ^
静默失败转为异常
所谓静默失败就是既不报错也没有任何效果,例如改变常量的值。在严格模式下,静默失败会转换成抛出异常。
例如:
1 | // 定义一个常量 |
以上代码在稍微老一点的浏览器可能并不会报错(新版报错),但开启严格模式后,一定会报错。
禁止delete关键字
在严格模式下不能对变量使用delete
运算符。
例如:
1 | var v = 100; |
- 严格模式下会抛出一个错误
- 非严格模式下会输出两个100
严格模式下禁用delete只针对删除变量,而不是数组元素和对象属性。
1 | ; |
对变量名的限制
在严格模式下,JavaScript对变量名也有限制。特别不能使用如下内容作为变量名:
implements
interface
let
package
private
protected
public
static
yield
上述关键词表示在ECMAScript的下一个版本中可能会用到他们,在严格模式下使用以上字符作为变量名会导致语法错误。
对象
不可删除的属性
1 | ; |
非严格模式下不会报错,但也不会删除成功。但在严格模式下会直接抛出错误。
但严格模式并不会限制所有对象,例如:
1 | ; |
即使在严格模式下,还是可以删除Math.random
方法。
属性名必须唯一
在严格模式下,一个对象内的所有属性名在对象内必须唯一。
1 | ; |
开启严格模式后,如果对象具有相同属性,那么并不会报错,而是覆盖。
只读属性的赋值
1 | ; |
对于不可修改的属性,无论是修改还是删除都会发生报错。
不可扩展的对象
在严格模式下,不能为不可扩展的对象添加新属性。
1 | ; |
以上代码在严格模式下会报错,非严格模式下不会报错。
函数
参数名必须唯一
在严格模式下,要求命名函数的参数必须唯一。
1 | function fn(a, a, b) { |
例如以上代码,非严格模式下会输出7,两个参数a都会被当作2;但在严格模式下,会抛出错误。
arguments的不同
在严格模式下, arguments对象的行为也有所不同。
- 非严格模式下,修改命名参数的值也会反应到arguments对象中。
- 严格模式下,命名参数与arguments对象是完全独立的。
1 | ; |
非严格模式下arguments对象获取参数的值与形参有关。(如果局部变量与形参名相同,则根据就近原则获取);严格模式下arguments对象获取参数的值与形参无关。
arguments.callee()
在严格模式下,不能使用armaments对象的callee()方法。
1 | ; |
以上代码在严格模式下会直接报错。
函数声明的限制
在严格模式下,只能在全局域和函数域中声明函数。
1 | ; |
在严格模式下,函数的定义只能在全局作用域与函数作用域,不能在块级作用域
增加eval()作用域
在严格模式下,使用eval()
函数创建的变量只能在eval()
函数内部使用。
1 | eval("var v = 100"); |
以上代码在非严格模式下会输出100
,而在严格模式下会抛出错误。
在严格模式下,会增加eval作用域。也就是说在eval函数定义的变量只能在当前eval函数使用。
arguments对象–禁止读写
在严格模式下,禁止使用eval()和arguments作为标示符,也不允许读写它们的值。
- 使用var声明。
- 赋予另一个值
- 尝试修改包含的值。
- 用作函数名。
- 用作命名的函数的参数。
- 在 try-catch语句中用作例外名。
以下语句在严格模式下均会报错:
1 | eval = 17; |
抑制this
- 在非严格模式下使用数的
apyly()
或call()
方法时,null
或undefined
值会被转换为全局对象。 - 在严格模式下,函数的
this
值始终是指定的值(无论什么值)。
1 | ; |
在严格模式下会抛出错误,必须明确指定this,例如fn.call(obj);
。