【JavaScript】Strict モード

Strict モード JavaScript

この記事では、ES5 で導入された Strict モードについて解説する。

Strict モードとは

デフォルトの厳格ではない JavaScript で許容されている一部の機能や書き方を制限するモードのこと。Strict モードを有効にするには、ファイルの先頭あるいは関数内の先頭で

'use strict';
function myfunc() {
  'use strict';
  // ...
}

あるいはダブルクウォートで

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

と記述する。

Strict モードの使用目的

Strict モードを使用する目的としては次のようなものがある。

  • バグの原因になりそうな一部の記述を禁止し、エラーを発生させる。
  • 将来の ECMAScript で使用される可能性のある予約語を確保する。

バグの原因になりそうな一部の記述を禁止し、エラーを発生させる

例えば、JavaScript のデフォルトのモードでは、var / let / const などのキーワードで宣言していない変数への代入は、グローバルオブジェクトの新しいプロパティの作成を意味する。

以下のサンプルを実行してみると、関数内での変数 msg への代入により、グローバルオブジェクト(window オブジェクト)に新しいプロパティ window.msg が作成されることが分かる。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>title</title>
</head>
<body>
  <script src="main.js"></script>
</body>
</html>
// main.js
function myfunc() {
  msg = 'Hello';
  console.log(msg);
}
myfunc();
// --> Hello

console.log(window.msg);
// --> Hello

しかし、’use strict’ により Strict モードを有効にすると、エラー「Uncaught ReferenceError: msg is not defined」が発生する。

function myfunc() {
  'use strict';
  msg = 'Hello';
  console.log(msg);
}
myfunc();
// --> Uncaught ReferenceError: msg is not defined

これにより、

  • var / let / const などのキーワードを付け忘れたことにより、誤ってグローバルな変数を定義してしまうこと
  • 変数名の綴りを間違えて代入文を実行してしまうこと

がエラーになり、このようなミスを防ぐことができる。

将来の ECMAScript で使用される可能性のある予約語を確保する

Strict モードでは、将来の ECMAScript で使用される可能性のある予約語を変数として使用できいない。使用するとエラーを発生する。(参考:MDN

'use strict';

const implements = 100;
// --> Uncaught SyntaxError: Unexpected strict mode reserved word

モジュールでは常に Strict モード

モジュール内では “use strict”; を記述しなくても常に Strict モードが適用される。次のサンプルでは、変数 msg を宣言なしで使用しているためエラーとなっている。

デフォルトのモードであれば、グローバルオブジェクト(window オブジェクト)にプロパティが追加されエラーにはならないはずだが、Strict モードが適用されているため、エラーとなっている。

// moduleA.js
function myfunc() {
  msg = 'Hello';
  console.log(msg);
}
myfunc();
// --> Uncaught ReferenceError: msg is not defined

class 内では 常に Strict モード

class の constructor やメソッドの中は常に Strict モードが適用される。そのため下のサンプルでは、class の constructor やメソッドの内部で定義した関数配下の this は undefined となり、一方 class 外で定義した関数配下の this は、Strict モードが適用されないのでグローバルオブジェクト(window オブジェクト)となっている。

function outerFunc(msg) {
  console.log(msg, this);
}

class MyClass {
  constructor() {
    function f() {
      console.log('constructor1:', this);
    }
    f();
    outerFunc('constructor2:');
  }

  method() {
    function f() {
      console.log('method1:', this);
    }
    f();
    outerFunc('method2:');
  }
}

const instance = new MyClass();
instance.method();

// constructor1: undefined
// constructor2: Window {window: Window, self: Window, document: document, name: "", location: Location, …}
// method1: undefined
// method2: Window {window: Window, self: Window, document: document, name: "", location: Location, …}

タイトルとURLをコピーしました