ECMAScript 5 引入了 strict mode ,如今已经被大多浏览器实现(从IE10开始)javascript
顾名思义,JavaScript 严格模式就是让 JS 代码以更严格的模式执行,不容许可能会引起错误的代码执行。在正常模式下静默失败的代码,严格模式下就会抛出错误。java
· 脚本文件范围webpack
将
"use strict";
放在脚本文件的第一行。整个脚本文件就会以“严格模式”执行。
· 函数做用域范围web
将
"use strict";
放在函数体的第一行,则整个函数以"严格模式"运行。
文件合并时,写在脚本文件第一行的 "use strict";
来实现严格模式会失效,能够将脚本文件的代码放在一个当即执行表达式中。数组
(funciton() { "use strict"; ... })()
也就是,变量必须声明后才能使用,正常模式直接赋值给一个未定义的变量时,会将变量定义为全局变量。浏览器
"use strict"; var a = b = 3; // Uncaught ReferenceError: b is not defined 以上代码等于: var a; b = 3; a = b;
this
关键字指向全局对象正常模式下,函数中若是没有指明 this
对象,JS 则会将 this
隐式指向为全局对象。若是绑定的值是非对象,将被自动转为对象再绑定上去,而 null 和 undefined
这两个没法转成对象的值,将被忽略。安全
严格模式下,必须指明 this
的指向对象。若是没有指明的话,this
的值为 undefined
函数
var name = "foo"; function func() { "use strict"; this.name; // Uncaught TypeError: Cannot read property 'name' of undefined } func(); // 没有加 new 关键字 new func(); function func() { return this } func() // window func.call(8) // Number {8} func.call(true) // Boolean {true} func.call("abcd") // {"abcd"} func.call(null) // window func.call(undefined) // window "use strict" function func() { return this } func() // undefined func.call(8) // 8 func.call(true) // true func.call(null) //null func.call(undefined) // undefined
禁止使用 arguments.callee、arguments.caller、fn.caller、fn.callee
;
在严格模式下,arguments.callee 是一个不可删除属性,并且赋值和读取时都会抛出异常优化
function func() { "use strict"; func.caller; // 报错 func.arguments; // Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them } func()
没法删除 var 声明的变量。this
在正常模式中,给对象的只读属性赋值, 删除对象的不可设置属性,添加不可扩展对象的新属性,会静默失败。
可是在严格模式中,会抛出错误。
另外,字符串的属性 length 也是只读属性,修改后会报错。
"use strict"; var str = "abc" str.length = 8 // Uncaught TypeError: Cannot assign to read only property 'length' of string 'abc' 'use strict'; var obj = Object.defineProperty({}, 'a', { value: 37, writable: false }); obj.a = 123; // Uncaught TypeError: Cannot assign to read only property 'a' of object '# 'use strict'; var obj = Object.defineProperty({}, 'p', { value: 37, configurable: false }); delete obj.p // Uncaught TypeError: Cannot delete property 'p' of #<Object> var obj = {}; Object.preventExtensions(obj); obj.title = "hello"; // Uncaught TypeError: Cannot add property title, object is not extensible
在正常模式中,对象的重名属性,位置靠后会覆盖位置靠前的重名属性。函数也是,函数体查找到的参数,靠后的重名参数会覆盖靠前的重名参数。
"use strict"; var o = { p: 1, p: 2 }; // IE报错:strict 模式下不容许一个属性有多个定义, 新版的 Chrome 和 firefox 并不会报错,会采用覆盖机制。 "use strict"; function func(a, a) { console.log(a) } func(1, 2) // IE报错: strict 模式下不容许正式参数名称重复。新版的 Chrome 和 firefox 并不会报错,会采用覆盖机制。
JavaScript 支持动态绑定,也就是 JavaScript 的属性和方法是在运行时肯定,而不是在编译时肯定。
因而,JavaScript 严格模式禁用了 with 语句, 由于使用了 with 语句,with 语句块中变量没法肯定是外部全局变量仍是传入的对象属性。
"use strict"; var x = 17; with (obj) // !!! 语法错误 { // 若是没有开启严格模式,with 中的这个x会指向 with 上面的那个 x,仍是obj.x? // 若是不运行代码,咱们没法知道,所以,这种代码让引擎没法进行优化,速度也就会变慢。 x; // Uncaught SyntaxError: Strict mode code may not include a with statement }
eval 关键字再也不会给上层函数(surrounding function)或者全局引入一个新的变量。在严格模式中,eval 语句会建立本身的一个做用域,eval 里的变量只能在 eval 内部使用。
严格模式规定名称为 eval 和 arguments 不能经过程序语法被绑定(be bound)或赋值
严格模式下,参数的值不会随 arguments 对象的值的改变而变化。
正常模式中,对参数从新赋值,会修改 arguments 类数组对象下的参数值。同时,修改 arguments 类数组对象的值,也会修改函数参数的值。
严格模式下,不只参数的值不会随着 arguments 类数组对象的变化而变化,参数的变化也不会引发 arguments 对象的变化,arguments 对象会记住参数的传入初始值。
function func(a) { "use strict" a = 8; // arguments[0] = 8 return [a, arguments[0]] } func(3) // [8, 3] function func(a) { "use strict" arguments[0] = 8 return [a, arguments[0]] } func(3) // [3, 8]
ES5 的严格模式只容许在全局做用域或函数做用域声明函数。也就是说,不容许在非函数的代码块内声明函数。
if (true) { function add() { } } add() for (var i = 0; i < 5; i++){ function f2() { } // !!! 语法错误 f2(); } 以上代码在严格模式是禁止的,可是在 ES6 中,是容许在代码块中声明函数的。
严格模式中一部分字符变成了保留的关键字。这些字符包括implements, interface, let, package, private, protected, public, static
和yield
。在严格模式下,你不能再用这些名字做为变量名或者形参名
function private() {"use strict" } //Uncaught SyntaxError: Unexpected strict mode reserved word
严格模式可以帮助咱们写出更安全,更有规范的代码,则应该避免一些危险的写法,采用更好的写法:
如今的 webpack 会在打包的时候默认是严格模式,因此如今不用再手动写 use strict
了。严格模式能帮助咱们以更规范的方式书写代码,可是不管是否严格模式,都应该注意代码的规范,避免隐式 bug 的出现。
2018/02/08 @Starbucks