概述
严格模式是ES5进入标准的
目的是为了:
- 明确禁止一些不合理 不严谨的语法 减少JS语言的一些怪异行为
- 增加更多报错的场合 保证代码运行的安全
- 提高编译效率 增加运行速度
- 为新版的JS语法做铺垫
如何开启
使用一段字符串 "use strict"
全局开启严格模式
use strict放在JS文件的第一行,整个JS都将以严格模式运行
'use strict'
console.log('这是严格模式')
----------
console.log('这是正常模式')
严格模式必须从代码一开始就生效
'use strict'
v=200;
console.log(v) //ReferenceError: v is not defined
----------
v=200;
console.log(v) //200
'use strict'
函数开启严格模式
use strict放在函数体的第一行,则整个函数以严格模式运行
function strict(){
'use strict' //开启严格模式
return '这是严格模式'
}
strict() //这是严格模式
如果一块代码是严格模式,另一块代码不是,它们的合并就可能出错。严格模式的代码在前,则合并后的代码都是严格模式;如果正常模式的代码在前,则合并后的代码都是正常模式。这两种情况下,合并后的结果都是不正确的。这时可以把整个代码放在一个立即执行的匿名函数之中。
(function(){
'use strict';
//其他代码
})()
显式报错
严格模式使得JS的语法变得更严格,更多的操作会显式报错。其中有些操作,在正常模式下只会静默失败,不会报错
只读属性不可写
严格模式下,对只读属性赋值会报错
'use strict'
var obj=Object.definedProperty({},'name',{
value:'Rookie',
writable:false
})
obj.name='Faker'; //TypeError: Cannot assign to read only property 'name' of object '#<Object>'
删除不可配置属性也会报错
'use strict'
var obj=Object.definedProperty({},'sex',{
value:'male',
configurable:false
})
delete obj.sex //TypeError: Cannot delete property 'sex' of #<Object>
只设置了取值器的属性不可写
严格模式下,对一个只有取值器(getter)、没有存值器(setter)的属性赋值,会报错
'use strict'
var obj={
get v(){return 1}
}
obj.v=2; //TypeError: Cannot set property v of #<Object> which has only a getter
禁止扩展的对象不可扩展
严格模式下,对禁止扩展的对象添加新属性会报错。
'use strict'
var obj={}
Object.preventExtensions(obj);
obj.name = 'object' //TypeError: Cannot add property name, object is not extensible
eval、arguments 不可用作标识名
严格模式下,使用eval或者arguments作为标识名,将会报错
'use strict'
var eval = 3;
var arguments =4;
function fn(eval){}
var fun =function eval(){}
var xxx=new Function('arguments',"use strict",return 17)
// SyntaxError: Unexpected eval or arguments in strict mode
函数不能有重名的参数
正常模式下,如果函数有多个重名的参数,可以用arguments[i]读取。严格模式下属于语法错误
function(a,a,b){
'use strict'
return a+b
} // SyntaxError: Duplicate parameter name not allowed in this context
arguments的不同
严格模式下 arguments对象的行为有所不同
- 非严格模式下 修改命名参数的值会反应到arguments对象中
- 严格模式下 命名参数与arguments对象是完全独立的
function fn(x){
x='Hello';
console.log(x); //Hello
console.log(arguments[0]) //Hello
};
fn('HOLA')
----------
function fn(x){
'use strict'
x='Hello';
console.log(x); //Hello
console.log(arguments[0]) //HOLA
};
fn('HOLA')
其他问题
禁止使用 arguments.callee
正常模式下调用没有什么作用,但是不会报错
var f =function(){
return arguments.callee
}
f()
严格模式明确规定,函数内部使用arguments.callee将会报错
var f=function(){
'use strict'
return arguments.callee
}
f() //TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
禁止删除变量
严格模式下无法删除变量,如果使用delete命令删除一个变量,会报错
'use strict'
var color ='red';
delete color //SyntaxError: Delete of an unqualified identifier in strict mode.
增加
正常模式下,JavaScript 语言有两种变量作用域(scope):全局作用域和函数作用域。严格模式创设了第三种作用域:eval作用域。
正常模式下,eval语句的作用域,取决于它处于全局作用域,还是函数作用域。严格模式下,eval语句本身就是一个作用域,不再能够在其所运行的作用域创设新的变量了,也就是说,eval所生成的变量只能用于eval内部 eval 作用域
(function () {
'use strict';
var x = 2;
console.log(eval('var x = 5; x')) // 5 eval语句内部是一个独立作用域,所以内部的变量x不会泄露到外部
console.log(x) // 2
})()
禁止this指向全局对象
正常模式下,函数内部的this可能会指向全局对象,严格模式禁止这种用法,避免无意间创造全局变量
function f() {
'use strict'
console.log(this === undefined);
}
f() //true 严格模式的函数体内部this是undefined
使用构造函数时 如果没有使用new关键字,这时this不再指向全局对象,而是报错
function f(){
'use strict';
this.a=1
}
f() //ReferenceError: f is not defined
严格模式下,函数直接调用时(不使用new调用),函数内部的this表示undefined(未定义),因此可以用call、apply和bind方法,将任意值绑定在this上面。正常模式下,this指向全局对象,如果绑定的值是非对象,将被自动转为对象再绑定上去,而null和undefined这两个无法转成对象的值,将被忽略
严格模式
'use strict';
function fun() {
return this;
}
console.log(fun()); //undefined
console.log(fun.call(2)); //2
console.log(fun.call(true)); // true
console.log(fun.call(null)); //null
console.log(fun.call(undefined)); //undefined
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。