Strictモード(厳格モード)とは?

JavaScriptの言語仕様は曖昧な部分が存在します。他の言語であればエラーになるはずの処理がStrictモードの宣言をしていなかった場合、処理が通ってしまい、エラーは発生していないが挙動がおかしくデバッグするのに一苦労なんてこともよくあります。こういったことのないように私はJavaScriptのコーディング時には必ずStrictモードの宣言をしています。そこでStrictモードでチェックされる内容をまとめておこうと思います。

Strictモードの宣言

Strictモードは、'use strict';と記述して宣言します。記述できる箇所とその適用範囲は以下の通り。

宣言箇所適用範囲
JavaScriptのソースコードの先頭ソースコード全体
JavaScriptの関数の先頭宣言した関数内
'use strict';

function foo() {
  'use strict';
}

Strictモードのチェック項目

それではStrictモードでチェックされる項目の例を挙げていこうと思います。検証ブラウザはGoogle Chromeで行っています。

宣言のない変数の使用禁止

JavaScriptで変数の宣言をする際に、var foo = 'bar';という感じでvariable宣言をするわけですが、Strictモードなしの場合、foo = 'bar';とvarなしで通ってしまいます。変数のスペルミスに気づかなかったり、変数のスコープが変わるので混乱します。ちゃんとvar宣言して使用するようにしましょう。

foo = 'bar';

// barと出力される
console.log(foo);

Strictモードを宣言するとコンソールに「fooは定義されていません」と参照エラーが出力されます。

'use strict';
foo = 'bar';

// ReferenceError: foo is not defined at xxxxx
console.log(foo);

8進整数リテラルの使用禁止

JavaScriptでは、先頭に0がつく数値は8進数として処理されます。今のモダンブラウザでは発生しないようですが、parseIntメソッドで基数を引数に渡さず、parseInt('0100');と処理した場合、10進数では「64」となります。こういうミスを防ぐためにもそもそも禁止にしておくほうが良いと思います。
※parseIntでちゃんと基数を渡せという話にもなりますけど。

var foo = 0100;

// 64と出力される
console.log(foo);

Strictモードを宣言するとコンソールに「Strictモードでは8進リテラルは許可されません」とシンタックスエラーが出力されます。

'use strict';
var foo = 0100;

// SyntaxError: Octal literals are not allowed in strict mode.
console.log(foo);

関数の引数名の重複禁止

JavaScriptでは、関数の引数名が重複していてもエラーになりません。引数名が重複していた場合、最後に定義した引数が有効になります。

function foo(bar, bar){
  console.log(bar + bar);
}
// bar2bar2が出力される
foo('bar1', 'bar2');
Strictモードを宣言するとコンソールに「重複するパラメータ名はこのコンテキストでは許可されません」とシンタックスエラーが出力されます。

'use strict';

function foo(bar, bar){
  console.log(bar + bar);
}
// SyntaxError: Duplicate parameter name not allowed in this context
foo('bar1', 'bar2');

将来の使用を見越した予約語の変数宣言禁止

JavaScriptのStrictモードでは、将来の使用を見越した予約語を変数名として使用することを禁止しています。現在の予約語は、Strictモードでなくてもエラーになりますが、let

var let = 'bar';

// barが出力される
console.log(let);
Strictモードを宣言するとコンソールに「予期しない厳密モード:予約語」とシンタックスエラーが出力されます。

'use strict';

var let = 'bar';

// SyntaxError: Unexpected strict mode reserved word
console.log(let);

with文の使用禁止

with文は引数で渡されたオブジェクトをブレス内のメソッドやプロパティを使用する際に省略できる記述方法です。しかし省略できるかわりに都度そのオブジェクトをスコープチェーンが発生して処理性能が低下してしまいます。したがって使用するのをやめましょう。

// foo, bar, baz が出力される
with (console) {
  log('foo');
  info('bar');
  warn('baz')
}
Strictモードを宣言するとコンソールに「Strictモードのコードにはwithステートメントが含まれていない可能性があります」とシンタックスエラーが出力されます。

'use strict';

// Strict mode code may not include a with statement
with (console) {
  log('foo');
  info('bar');
  warn('baz')
}

まだあるチェック項目

まだ他にStrictモードでチェックされる処理はあるのですが、とりあえず代表的なものを。また追記していきます。

参考サイト

Strictモード(MDN)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Strict_mode
JavaScriptの予約語(MDN)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Reserved_Words