亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

全部開發者教程

JavaScript 入門教程

嚴格模式

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 的文檔。