- 小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
背景
一直码于业务中,却疏忽了最基础的知识,相信很多人都听过严格模式和非严格模式,但是却不知道具体的区别,通过本篇,我们带大家去理解总结严格模式和非严格模式的区别。
严格模式
ES5 为这个语言新增了“严格模式”,严格限制了某些行为的规则。一般来说,这些限制 可以将代码保持在一个更安全、更适当的规范集合之内。另外,遵循严格模式也更容易让 引擎优化你的代码。严格模式是代码的一次重大突破,你应该在自己的程序中一直使用。
如果代码中使用"use strict"开启了严格模式
,则下面的情况都会在脚本运行之前抛出[SyntaxError]异常:
-
八进制语法
:var n = 023和var s = "\047"
-
[
with
]语句 -
使用[delete]删除一个变量名(而不是属性名)
:delete myVariable
-
使用
eval
或arguments
作为变量名或函数名 -
使用未来保留字(也许会在ECMAScript 6中使用):
implements
,interface
,let
,package
,private
,protected
,public
,static
,和yield
作为变量名或函数名 -
在语句块中使用函数声明:
if(a<b){ function f(){} }
-
其他错误
- 对象字面量中使用两个相同的属性名:
{a: 1, b: 3, a: 7}
- 函数形参中使用两个相同的参数名:
function f(a, b, b){}
- 对象字面量中使用两个相同的属性名:
这些错误是有利的,因为可以揭示简陋的错误和坏的实践,这些错误会在代码运行前被抛出
变量
严格模式下如何创建变量及何时会创建变量都会发生变化。第一个变化是不允许意外创建全局变 量。在非严格模式下,以下代码可以创建全局变量:
// 非严格模式:创建全局变量
// 严格模式:抛出 ReferenceError
message = "Hello world!";
对象
严格模式下,。在使用对象字面量时,属性名必须唯一。
// 两个属性重名
// 非严格模式:没有错误,第二个属性生效
// 严格模式:抛出 SyntaxError
let person = { name: "Nicholas", name: "Greg" };
函数
// 命名参数重名
// 非严格模式:没有错误,只有第二个参数有效
// 严格模式:抛出 SyntaxError function sum (num, num){ // 函数代码 }
this
使用函数的 apply()或 call()方法时,在非严格模式下 null 或 undefined 值会被强制 转型为全局对象。在严格模式下,则始终以指定值作为函数 this 的值,无论指定的是什么值。例如:
// 访问属性
// 非严格模式:访问全局属性
// 严格模式:抛出错误,因为 this 值为 null let color = "red";
function displayColor() { alert(this.color); }
displayColor.call(null);
类与模块
对于类,这包括类声明和类表达式,构造函数、实例方法、静态方法、获取方法和设置方法都在严 格模式下。对于模块,所有在其内部定义的代码都处于严格模式。
其他变化
严格模式下还有其他一些需要注意的变化。首先是消除 with 语句。with 语句改变了标识符解析 时的方式,严格模式下为简单起见已去掉了这个语法。在严格模式下使用 with 会导致语法错误:
// 使用 with 语句
// 非严格模式:允许
// 严格模式:抛出 SyntaxError with(location) { alert(href); }
严格模式也从 JavaScript 中去掉了八进制字面量。八进制字面量以前导 0 开始,一直以来是很多错 误的源头。在严格模式下使用八进制字面量被认为是无效语法:
// 使用八进制字面量
// 非严格模式:值为 8
// 严格模式:抛出 SyntaxError let value = 010;
ECMAScript 5修改了非严格模式下的parseInt(),将八进制字面量当作带前导0的十进制字面量。
// 在 parseInt()中使用八进制字面量
// 非严格模式:值为 8
// 严格模式:值为 10
let value = parseInt("010");
总结
推荐使用严格模式,因为能让代码更规范,也更利于后期的维护和排除错误。更加严谨。