严格模式
ES5首次引入严格模式的概念,即以更严格的模式检查Javascript代码的错误,可以应用到全局或者函数内部。
使用
使用严格模式,只需要在JavaScript代码前或函数体内部前,声明一个不赋值给任何变量的字符串
"use strict"
也可以在函数体内部开启严格模式
function fun(){
"use strict"
//其他代码
}
变量
严格模式下
- 给未声明的变量赋值会抛出错误
- 删除变量将会出错 delete
- 增加限制,不允许变量名为implements interface let private public static yield等保留字
对象
严格模式下
- 给只读属性赋值会抛出 TypeError
- 在不可配置属性上使用delete会抛出TypeError
- 给不存在的对象添加属性会抛出TypeError
另外,对象中的属性名必须唯一
let person = {
name: "张三"
name: "李四"
}
非严格模式下,第二个属性生效,严格模式下会抛出SyntaxError错误
但ES6删除了这个限制
函数
严格模式要求函数形参必须唯一
function sum(num, num){
//do something
}
在非严格模式下,这个函数声明ok,但函数内num为第二个值
在严格模式下,不允许形参重名,且arguments对象在严格模式下有一些变化
在非严格模式下,修改命名参数也会修改arguments对象中的值,而在严格模式中,参数与arguments是互相独立的,例如
function print(value){
value = 'b'
console.log(value)
console.log(arguments[0])//非严格模式下:b,严格模式下:a
}
print('a')
并且严格模式下去掉了arguments.callee与arguments.caller,在非严格模式下,它们分别引用函数本身,与调用函数,关于函数的另一个变化是不允许函数声明,除非他们位于脚本或函数的顶级,即在if中声明函数会出错
函数参数
ES7增加了一条限制,任何使用剩余运算符、解构操作符、默认参数的函数内部都不能使用严格模式
eval()
严格模式下,eval()函数不会在包含上下文中创建变量或函数,例如
function fun(){
eval("var x = 10")//let会报错
console.log(x)//非严格模式下x=10,严格模式下出错,因为没有x变量
}
fun()
然而,变量和函数可以在eval()中声明,但他们位于代码执行期间一个特殊的作用域中,代码执行完毕就会被销毁。因此,下面代码就不会报错
"use strict"
let result = eval("let x=10,y=11;x+y")
console.log(result)
严格模式下,不允许使用eval,arguments作为标识符
let eval=10
等都是错误的
this 强制转换
在使用函数apply()与call()方法时,非严格模式下,null或undefined会被强制转型为全局对象,在严格模式下,则始终以指定值作为函数this的值,无论指定的是什么值。例如
let color = 'red'
function print(){
console.log(this.color)
}
print(null)
调用时,传入null作为this的值,在非严格模式下,打印red,严格模式下this为null,抛出错误
通常,函数会将this转型为对象类型,这种行为被称为“装箱”,所以原始值会转型为他们的包装对象类型
function fun(){
console.log(this)
}
fun()//非严格模式:window 严格模式:undefined
fun(1)//非严格模式:Number{1} 严格模式:1
在严格模式下,this的值不会再“装箱”
类与模块
ES6类和模块中定义的所有代码默认都处于严格模式
其他变化
严格模式取消了with语法
取消了八进制字面量,八进制字面量以0开始,容易出错let a=010
非严格模式,a=8