章节索引 :

严格模式

JavaScript 的严格模式是使用受限制的 JavaScript 的一种方式,从而隐式地退出“草率模式”。严格模式不仅仅是一个子集:这种模式有意地与普通情形下的代码有所区别。(MDN)

严格模式为 JavaScript 提供了一个更严格的运行环境。

开启严格模式后,部分特性会发生改变,如 this 指向 window 的函数不再指向 window,而是变成了 undefined

function Test() {
  'use strict';
  console.log('this:', this);
}

Test(); // 输出:this: undefined

1. 开启严格模式

1.1 对单个 script 标签或者 js 文件开启严格模式

单个 js 文件或者 script 标签的严格模式,可以通过在所有代码执行前加上 'use strict' 字符串开启。

'use strict';

function Test() {
  console.log('this:', this);
}

Test(); // 输出:this: undefined

图片描述

1.2 对一个函数开启严格模式

在函数顶端协商 'use strict' 字符串,就可以打开整个函数的严格模式。

function testWith() {
  'use strict';

  var person = {
    name: '鸽子天王',
    age: 12,
  };

  var age = 11;

  with (person) {
    console.log(name);
    console.log(age);
  }
}

testWith();

在严格模式下是不提供 with 语句的调用的,所以这里会爆 Strict mode code may not include a with statement 错误。

2. 严格模式的规范

2.1 禁止使用 with

在严格模式下是禁止使用 with 语句的。

'use strict';
var person = {
  name: '鸽子巨星',
};

with (person) {
  console.log(name);
}

图片描述

2.2 变量必须被声明

在严格模式下,变量必须被声明才能使用,否则会报错。

// 非严格模式下
number = 1;

console.log(number); // 输出:1
// 严格模式下
'use strict';

number = 1; // 报错:ReferenceError: number is not defined

图片描述

2.3 eval 会创建自己的作用域

非严格模式下的 eval 作用域是其本身所在的作用域,而严格模式下,eval 执行过程中会创建一个新的作用域,并在结束后销毁。

// 非严格模式下

var number = 1;

eval('var number = 3; console.log(number)'); // 输出:3

console.log(number); // 输出:3

图片描述

// 严格模式下
'use strict';

var number = 1;

eval('var number = 3; console.log(number)'); // 输出:3

console.log(number); // 输出:1

图片描述

2.4 函数的 arguments 不能被修改

在非严格模式下,函数的 arguments 可以被重新赋值,在严格模式下,做赋值操作会报错。

function fn() {
  console.log(arguments);

  arguments = 1;

  console.log(arguments);
}

fn(1, 2, 3);

图片描述

'use strict';
function fn() {
  console.log(arguments);

  arguments = 1;

  console.log(arguments);
}

fn(1, 2, 3);

图片描述

2.5 函数的 this 规则有些变化

this 章节中讨论了不同情况的指向,其中有一种情况函数的 this 是指向 window 的。

在严格模式中,这种情况下的 this 会变成 undefined

function testThis() {
  console.log(this);
}

testThis();

图片描述

// 严格模式下
'use strict';
function testThis() {
  console.log(this);
}

testThis();

图片描述

2.6 caller 与 arguments.callee 被禁用

arguments.caller 可以获取到调用当前函数的函数的引用(该属性已经被标准废弃,不再使用了)。

arguments.callee 则可以获取到当前函数的引用。

这两个属性在严格模式下都被禁用。

function fn1() {
  console.log(arguments.callee === fn1);
}

fn1();

图片描述

'use strict';
function fn1() {
  console.log(arguments.callee === fn1);
}

fn1();

图片描述

2.7 删除 configurable 为 false 的属性时报错

在非严格模式下,这种情况会直接忽略。

var obj = {};

Object.defineProperty(obj, 'prop', {
  configurable: false,
  value: 1,
});

console.log(obj);

delete obj.prop;

console.log(obj);

图片描述

'use strict';
var obj = {};

Object.defineProperty(obj, 'prop', {
  configurable: false,
  value: 1,
});

console.log(obj);

delete obj.prop;

console.log(obj);

图片描述

2.8 修改 writable 为 false 的属性时会报错

在非严格模式下,这种情况会直接忽略。

var obj = {};

Object.defineProperty(obj, 'prop', {
  writable: false,
  value: 1,
});

console.log(obj.prop);

obj.prop = 2;

console.log(obj.prop);

图片描述

'use strict';
var obj = {};

Object.defineProperty(obj, 'prop', {
  writable: false,
  value: 1,
});

console.log(obj.prop);

obj.prop = 2;

console.log(obj.prop);

图片描述

2.9 禁止书写八进制的字面量

八进制的表示是在数字前面加一个 0,但其实 ECMAScript 标准中并没有这种表示法。

在 ES6 中提供了八进制数的表示方式,即在数字前加上 0o 前缀。

在严格模式下是禁止使用 0 前缀表示的八进制字面量的。

// 非严格模式中

var num = 010;

console.log(num); // 输出:8
// 严格模式下

'use strict';
var num = 010;

console.log(num); // 输出:8

图片描述

2.10 新增了一些不能作为变量的关键字

许多关键字在非严格模式下是可以当作变量名的。

var yield = 1;

console.log(yield);

图片描述

'use strict';

var yield = 1;

console.log(yield);

图片描述

根据 MDN 提供的内容,保留字有:

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • yield

3. 小结

对严格模式大多数需要注意的是他带来的一些语法上的改变,特别是有些写法,在之前是不会报错的,开启严格模式后就会报错,如果没有进行错误处理,就会导致程序的中断。

以上对严格模式下的改变不一定是全部,可以参考 MDN 的文档。

前置知识
什么是JavaScript 开发与学习环境准备 调试方案
基础
JavaScript 变量 JavaScript 数据类型 JavaScript if 语句 JavaScript for 语句 JavaScript 算数运算符 JavaScript 比较运算符 JavaScript 逻辑运算符 JavaScript 表达式 JavaScript 函数 JavaScript 对象 JavaScript 字符串 JavaScript 数字 JavaScript 数组 JavaScript switch 语句 JavaScript while 语句 JavaScript break与continue JavaScript with document.cookie
内置对象
JavaScript Function JavaScript Math JavaScript Date JavaScript RegExp JavaScript JSON
JavaScript 与 DOM
什么是DOM DOM和JavaScript的关系 获取和操作 DOM 节点 JavaScript DOM与事件 JavaScript DOM 事件绑定 JavaScript DOM 事件对象 JavaScript DOM 事件流 JavaScript DOM 事件优化 JavaScript DOM 自定义事件
表单处理
使用 JavaScript 校验表单
BOM
BOM window 对象 常用的 BOM 相关对象 BOM 常用属性和方法
AJAX
JavaScript AJAX
进阶知识
JavaScript 异常处理 JavaScript 三元运算符 JavaScript 逗号操作符 JavaScript void JavaScript typeof JavaScript delete JavaScript debugger JavaScript getter &setter JavaScript 原型 JavaScript new操作符和构造函数 JavaScript instanceof JavaScript this JavaScript 严格模式 JavaScript 作用域 JavaScript 闭包 JavaScript 变量提升 JavaScript 对象包装器
常用库
jQuery Lodash moment.js swiper
进阶指南
ECMAScript6 Node.js Babel CSS 预处理器 代码规范 TypeScript Web Components 小程序 Vue / React / Angular JavaScript 关键字
常见疑点与误区
分号问题 对象属性访问问题 this 使用问题 浮点数精度问题 独一无二的 NaN 避免全局污染 控制台观察对象问题 根据环境选择语言特性
扩展
相关资源