javascript严格模式

概述

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

严格模式有哪些不同

  1. 不允许未声明的变量被赋值(见上例)

  2. 将拼写错转成异常

"use strict";
// 假如有一个全局变量叫做mistypedVariable
mistypedVaraible = 17; // 因为变量名拼写错误,这一行代码就会抛出 ReferenceError

  1. 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果):

"use strict";
delete Object.prototype; // 抛出TypeError错误

  1. 对象字面量重复属性名报错
    正常模式下重名属性是允许的,最后一个重名的属性决定其属性值。因为只有最后一个属性起作用,当代码是要改变属性值而却不是修改的最后一个重名属性的时候,复制这个对象就产生一连串的bug。在严格模式下,重名属性被认为是语法错误:

"use strict";
var o = { p: 1, p: 2 }; // !!! 语法错误

  1. 严格模式禁止八进制数字语法.
    测试如下:

!function(){
console.log(0123); //八进制字面量不被允许
}();
报错信息如下:

$ node 严格模式.js
D:\js\严格模式.js:19
console.log(0123); //八进制字面量不被允许
^^^^
SyntaxError: Octal literals are not allowed in strict mode.

  1. 禁止使用with语句
    因为with语句无法在编译时就确定,属性到底归属哪个对象。严格模式下, 使用 with 会引起语法错误, 所以就不会存在 with 块内的变量在运行是才决定引用到哪里的情况了

"use strict";
var x = 17;
with (obj) // !!! 语法错误
{
// 如果没有开启严格模式,with中的这个x会指向with上面的那个x,还是obj.x?
// 如果不运行代码,我们无法知道,因此,这种代码让引擎无法进行优化,速度也就会变慢。
x;
}

  1. 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

  1. 严格模式禁止删除声明变量。delete name 在严格模式下会引起语法错误:

"use strict";

var x;
delete x; `// !!! 语法错误

  1. this不再指向全局对象
    一个开启严格模式的函数,指定的this不再被封装为对象,而且如果没有指定this的话它值是undefined

function 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

  1. 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 ]

参考资料

MDN文档
阮一峰老师的博客

关键字:JavaScript, 严格模式, es5

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部