概述
严格模式是什么
严格模式是JavaScript中的一种限制性更强的变种方式。
严格模式可以和非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。严格模式的目的
- 严格模式会将js陷阱直接变成明显的错误
- 严格模式修正了一些引擎难以优化的错误:同样的代码有些时候在严格模式下更快
- 严格模式禁用了一些课鞥在未来版本中定义的语法
开启严格模式
在js中想要开启严格模式,需要在代码之前定义一个不会赋给任何变量的固定的字符串
'use strict';或者"use strict";//全局作用域开启严格模式'use strict';//函数作用域开启严格模式function fun (){ 'use strict'//作用于函数作用域 //其他代码}
变量
禁止意外的创建变量
在严格模式下,创建变量必须使用var关键字声明变量
//全局开启严格模式'use strict';//创建全局变量,但不使用var关键字//num = 233;//在非严格模式定义变量可以不使用var关键字,严格模式报错//console.log(num);//ReferenceError: num is not defined/*function fun() { v = 100;//在函数作用域中定义变量不适用var关键字,自动提升为全局变量 console.log(v)}fun();//ReferenceError: v is not defined*/function fn() { var a = 200; console.log(a)}fn();//200
静默失败转为异常
所谓静默失败就是既不报错也没有任何效果,例如改变常量的值。在严格模式下,静默失败会转为报错。
'use strict'const v = 23;//非严格模式下会静默失败v = 10;//TypeError: Assignment to constant variable.##禁用delete关键字在严格模式下,不能对变量使用delete关键字
'use strict'
//定义全局变量var v = 23;delete v;//严格模式:SyntaxError: Delete of an unqualified identifier in strict mode.console.log(v);//非严格模式:undefined //严格模式下delete关键字只是不能对变量使用##对变量名的限制在严格模式中,不能使用保留字作为变量名,会导致语法错误在非严格模式中可以使用保留字作为变量名![clipboard.png](/img/bVbfPEs)
'use strict';
var let = 23;//抛出错误:SyntaxError: Unexpected strict mode reserved word#对象##不可删除的属性在严格模式下,不能用delete运算符删除不可删除的属性。
'use strict';
delete Object.portotype;//抛出错误:TypeError: Cannot delete property 'prototype' of function Object() { [native code] }//非严格模式下:静默错误##属性名必须唯一在严格模式下,一个对象内的所有属性名必须唯一。
'use strict'
var v { a = 1,//严格模式下对象内的同名属性编辑器会报错,运行时不报错、输出结果与非严格模式一致 a = 2};console.log(v.a)//2##只读属性的赋值在严格模式下,不能为一个只读的属性赋值,会报错/非严格模式下,静默失败。
'use strict'
var obj = {name : '火锅'
};
//获取属性描述符console.log(Object.getOwnPropertyDescriptor(obj,'name'));//给对象obj添加只读属性Object.defineProperty(obj,'age',{value:2
});
console.log(Object.getOwnPropertyDescriptor(obj,'age'));//给只读属性赋值 - 只读属性不能赋值,非严格模式下静默失败
obj.age = 3;//严格模式:TypeError: Cannot assign to read only property 'age' of object '#<Object>'console.log(obj.age);##不可扩展的对象在严格模式下,不能为不可扩展的对象去添加新属性
'use strict';
//创建一个空对象var obj = {};//将对象设置为不可扩展 - 即不能添加新属性Object.preventExtensions(obj);//为对象添加新属性 - 非严格模式:静默失败obj.name = '九筒';//严格模式:TypeError: Cannot add property name, object is not extensibleconsole.log(obj.name);#函数##参数名必须唯一在严格模式中,要求命名函数的的参数必须唯一。非严格模式:最后一个重名参数会覆盖之前的重名参数。
'use strict'
function fun (a,a,b){//严格模式:重名参数被认为语法错误 console.log(a+a+b)//抛出错误:SyntaxError: Duplicate parameter name not allowed in this context}fun(1,2,3)##arguments 的不同- 严格模式:argumengs不受形参影响- 非严格模式:argumengs与形参有关
function fun (value){
var value = '火锅'; console.log(value);//火锅 - 就近原则 console.log(arguments[0])//严格模式:九筒 非严格模式:火锅 - 就近原则
}
fun('九筒');##arguments对象的callee()方法在严格模式中,不能使用arguments对象的callee()方法非严格模式下使用arguments.callee表示调用函数本身。
'use strict'
function fun (){return arguments.callee;//抛出TypeError错误
}
##函数声明的限制在严格模式下,只能在全局作用域和函数作用域中声明函数非严格模式可以在任意位置声明函数
'use strict'
if(true){ function fun (){}//在块级作用域(非全局和函数作用域)声明函数:语法错误}fun()// 抛出错误 ReferenceError: fun is not defined#增加eval()作用域在严格模式中,使用eval()函数创建的变量只能在eval()函数内部使用非严格模式下,eval()函数创建的变量可以在其他位置使用
'use strict'
eval('var v = 23');console.log(v);//抛出eferenceError: v is not defined#禁止读写在严格模式下:禁止使用eval()和arguments作为标识符,也不允许读写他们的值
"use strict";
//以下全部语法错误var eval = 12eval = 17;arguments++;++eval;var obj = { set p(arguments) { } };var eval;try { } catch (arguments) { }function x(eval) { }function arguments() { }var y = function eval() { };var f = new Function("arguments", "'use strict'; return 17;");#this关键字抑制this - 非严格模式使用apply()和call()方法时,null或undefined值会转换为全局对象- 严格模式下,函数的this值始终是指定的值(无论是什么值)
'use strict'
var v = 2;function fun (){ console.log(this.v);}var obj ={ v : 3};fun.call(null);// TypeError: Cannot read property 'v' of null