什么是 JavaScript 严格模式,一次性给你讲清楚(二)

283 阅读3分钟

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

除了使用一些第三方插件之外,还有什么办法可以提前发现一些比较直观的错误? 答案就是使用 JavaScript 的严格模式。

什么是严格模式

在 ES5 的时候,JS 首次引入了严格模式的概念,它会以更严格的条件去检查你的代码错误,它可以全局使用,也可以局部使用(应用到函数内部)。理解严格模式的规则是非常有必要的,在未来,ECMAScript 会逐步强制全局使用严格模式。

如何使用

非常简单,提供一个不赋值给任何变量的字符串即可。这个字符串为:

"use strict"

你可以在 JS 文件中任何地方声明这个字符串,如果不是声明在函数内部,则表示该模式引用到全局。在函数内部开启严格模式的例子如下:

function demo(){
	"use strict"
	// do something...
}

严格模式下的函数使用

函数参数必须唯一

严格模式下要求命名函数的参数必须是唯一的,否则抛出语法错误。而非严格模式下,则最后声明的参数才能生效。

function foo(p1, p1){
	//...
}
// SyntaxError

参数和 arguments 相互独立

在严格模式下,如果修改参数值,不会影响 arguments 的变化,而在非严格模式下,参数值发生变化,arguments 也会同样修改。

function foo(p1){
	p1 = "Sam";
	
	console.log(p1) // "Sam"
	console.log(arguments[0]) 
	// 严格模式下 "Echo"。非严格模式下 "Sam"
}

foo("Echo");

去掉了.callee和 .caller

在非严格模式下,arguments.callee 和 arguments.caller 分别代表引用函数本身和调用函数。在严格模式中,这两个都被去掉了,访问任何一个都会抛出 TyepError 异常。 另外,在非严格模式下,在 if 语句内声明函数会被自动提升到 if 语句外部,而在严格模式下,将会直接抛出语法错误。

特定函数参数内不允许使用严格模式

在 ES6 之后,参数允许有了一些便捷的操作,例如剩余操作符、解构操作符和默认参数。但在 ES7 新加了一条,用了以上特殊操作的函数内部,不允许声明严格模式。示例:

// 可以
function foo(a, b, c) {
  "use strict";
}

// 不可以
function bar(a, b, c='d') {
  "use strict";
}

// 不可以
function baz({a, b, c}) {  
	"use strict";
}

// 不可以
function qux(a, b, ...c) {
  "use strict";
}

ES6增加的这些新特性期待参数与函数体在相同模式下进行解析。如果允许编译指示"use strict"出现在函数体内,JavaScript解析器就需要在解析函数参数之前先检查函数体内是否存在这个编译指示,而这会带来很多问题。为此,ES7规范增加了这个约定,目的是让解析器在解析函数之前就确切知道该使用什么模式。

欢迎阅读其它文章