一篇文章图文并茂地带你了解 JavaScript 严格模式(strict mode)

JavaScript 严格模式 use strict

前言

在很长的一段时间内,JavaScript 是兼容性发展的。这意味着新的语言特性并不会影响原有的代码。但是也带来了一些缺点,一些 JavaScript 的设计者做出的不太好的决定或失误被永远的加入了JavaScript

这种情况直到 ES5 的出现得到了改变。我们可以在代码的首部添加特殊的指令 use strict 来使某些不良的 JavaScript 特性得到改善。

本文对于读者来说是补充知识的文章,由于现在许多前端学习者包括笔者是从 ES6 语法后才开始学的 JavaScript 。因此其实已经站在巨人的肩膀上,尽管没有特殊表明使用严格模式,却没有使用 JavaScript 内的 "糟粕"。

因此本文较适合想补充更多知识,了解 JavaScript 历史的读者,或是跟着比较老旧教程学习,曾经在几年前学习过 JavaScript 的读者。

严格模式 use strict

use strict 指令可以在代码的头部使用,如果放在代码的头部,则认为整个文件都将采用严格模式。

"use strict";	 // or 'use strict';
a = 1; 			// a is not defined

如果放在函数开始,则认为只有某个函数用了严格模式,如

(function() {
    "use strict";    
    // ...
})

需要注意,严格模式一旦开启,就不能 "反悔",即没有指令可以暂停严格模式。

什么时候需要严格模式?

除非有老旧代码,大多数情况下我们都推荐使用严格模式。

不过如果在模块或者类等现代 JavaScript 语言特性中,可以省略 use strict,因为已经默认开启了严格模式。

class Person {
    constructor() {
        age = 22;
    }
}
new Person(); // age is not defined

注: 只是对这些语法使用的地方生效,并非使用了类,就对整个文件生效严格模式。

class Person {}
a = 1; // ok

严格模式对编码的影响

1. 全局变量显式声明

age = 22; // window.age = 22

本来为了方便初学者,有意让变量在使用前无须声明。但是这些忘记声明的变量都成为了全局变量。在严格模式下,必须显式声明。

"use strict"

age = 22; // age is not defined

2. 禁止使用 with 语句

JavaScript 语言允许 动态绑定,意味着某些属性和方法到底属于哪个对象,不是编译的时候确定,而是运行的时候确定的。这会减慢 JavaScript 处理器的处理速度。

严格模式对动态绑定做了限制。

JavaScript 提供了 with 语句,本意是快捷访问对象的属性。不幸的是,结果可能不可预料。

with(obj) {
    a = b;
}

可能和下面某个语句是一致的

a = b;
obj.a = b;
a = obj.b;
obj.a = obj.b;

通过阅读代码,无法确定会执行某一条语句。

  1. 禁止 this 关键字指向全局对象

如果没有明确指明是谁调用的函数,在浏览器下,默认是 window

function Person() {
    this.name = "huro";
}

const p = Person();

这使得我们给 window.name 赋值了 huro

实际上或许我们是漏了 new 关键字。

但没有任何方式可以区分一个函数是构造函数还是普通函数。

在严格模式下直接调用函数 this 不再指向全局对象,而是 undefined

"use strict";
function Person() 
    this.name = "huro";
}
const p = Person(); // can't set property of undefined
  1. 更多的作用域

正常模式下,JavaScript语言有两种变量作用域

  1. 全局作用域
  2. 函数作用域
function fn(){
    // 函数作用域
}

在严格模式下,有额外的两种变量作用域

  1. 块级作用域

需要注意的是,由于 ES6 新增了 const 以及 let 语法,因此使用这两种语法定义的变量默认就有块级作用域。

"use strict";
if (true) {
    // 块级作用域
}
  1. eval 作用域
"use strict";
eval("console.log('huro')")

对于更多的 strict mode 下的影响。

可以参阅 阮一峰 strict mode 不过笔者认为里面的内容已经有些老旧了。

也可以参阅 MDN Strict mode

总结

严格模式可以说是摒弃了非常多 JavaScript 的语言糟粕,同时也为 ES5 以后的新增的语法特性做铺垫。

posted @ 2021-02-10 17:55  Huro~  阅读(119)  评论(0编辑  收藏  举报