概述
ECMAScript 5的严格模式是JavaScript中的一种限制性更强的变种方式。严格模式不是一个子集:它在语义上与正常代码有着明显的差异。不支持严格模式的浏览器与支持严格模式的浏览器行为上也不一样, 所以不要在未经严格模式特性测试情况下使用严格模式。严格模式可以与非严格模式共存,所以脚本可以逐渐的选择性加入严格模式。
严格模式在语义上与正常的JavaScript有一些不同。 首先,严格模式会将JavaScript陷阱直接变成明显的错误。其次,严格模式修正了一些引擎难以优化的错误:同样的代码有些时候严格模式会比非严格模式下更快。 第三,严格模式禁用了一些有可能在未来版本中定义的语法。
如果你想让你的JavaScript代码在严格模式下运行,可以参考转换成严格模式。
开启严格模式
作用于整个脚本文件
需要在所有语句之前放一个特定语句 "use strict"
; (或 'use strict';)注意必须是脚本开始第一行,否则无效
// 整个语句都开启严格模式的语法
"use strict";
var v = "Hi! I'm a strict mode script!";
合并不同模式的代码文件成一个文件,需要特别注意:
这种语法存在陷阱,有一个大型网站已经被它坑倒了:不能盲目的合并冲突代码。试想合并一个严格模式的脚本和一个非严格模式的脚本:合并后的脚本代码看起来是严格模式。反之亦然:非严格合并严格看起来是非严格的。合并均为严格模式的脚本或均为非严格模式的都没问题,只有在合并严格模式与非严格模式有可能有问题。建议按一个个函数去开启严格模式(至少在学习的过渡期要这样做)
作用于单个函数
同样讲'use strict';
置于函数开始的第一行
测试生效:
!function(){
'use strict';
x=1;
console.log(x); //因严格模式不允许未声明的变量被赋值,会报错
}();
报错信息:
$ node 严格模式.js
D:\js\严格模式.js:3
x=1;
^
ReferenceError: x is not defined
如果不是放在第一行没有进入严格模式,结果会是1
严格模式有哪些不同
不允许未声明的变量被赋值(见上例)
-
将拼写错转成异常
"use strict"; // 假如有一个全局变量叫做mistypedVariable mistypedVaraible = 17; // 因为变量名拼写错误,这一行代码就会抛出 ReferenceError
-
在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果):
"use strict"; delete Object.prototype; // 抛出TypeError错误
-
对象字面量重复属性名报错
正常模式下重名属性是允许的,最后一个重名的属性决定其属性值。因为只有最后一个属性起作用,当代码是要改变属性值而却不是修改的最后一个重名属性的时候,复制这个对象就产生一连串的bug。在严格模式下,重名属性被认为是语法错误:"use strict"; var o = { p: 1, p: 2 }; // !!! 语法错误
-
严格模式禁止八进制数字语法.
测试如下:!function(){ console.log(0123); //八进制字面量不被允许 }();
报错信息如下:
$ node 严格模式.js D:\js\严格模式.js:19 console.log(0123); //八进制字面量不被允许 ^^^^ SyntaxError: Octal literals are not allowed in strict mode.
-
禁止使用with语句
因为with语句无法在编译时就确定,属性到底归属哪个对象。严格模式下, 使用 with 会引起语法错误, 所以就不会存在 with 块内的变量在运行是才决定引用到哪里的情况了"use strict"; var x = 17; with (obj) // !!! 语法错误 { // 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x? // 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。 x; }
-
eval 独立作用域
在严格模式下 eval 仅仅为被运行的代码创建变量,eval作用域内不再能够生成全局变量了,它所生成的变量只能用于eval内部。var x = 17; var evalX = eval("'use strict'; var x = 42; x"); console.log(x === 17); //true console.log(evalX === 42); //true
-
严格模式禁止删除声明变量。delete name 在严格模式下会引起语法错误:
"use strict"; var x; delete x; `// !!! 语法错误
-
this不再指向全局对象
一个开启严格模式的函数,指定的this不再被封装为对象,而且如果没有指定this的话它值是undefinedfunction fun() { return this; } console.log(fun() === undefined); //true console.log(fun.call(2) === 2); //true console.log(fun.apply(null) === null); //true console.log(fun.call(undefined) === undefined); //true console.log(fun.bind(true)() === true); //true
-
arguments变为参数的静态副本
严格模式下,函数的 arguments 对象会保存函数被调用时的原始参数。arguments[i] 的值不会随与之相应的参数的值的改变而变化,同名参数的值也不会随与之相应的 arguments[i] 的值的改变而变化。function f(a) { "use strict"; a = 42; return [a, arguments[0]]; } var pair = f(17); console.log(pair); //[ 42, 17 ]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。