【STEP.04】
Strictモードの使い方をマスターしよう!

Strictモードとは

長い歴史を持つJavaScriptには、「仕様としては存在するが、現在では安全性や効率面で利用すべきではない構文」が存在します。

以前は、こうした構文の落とし穴を開発者が学んで、落とし穴を避けるようにコーディングしなければなりませんでした。

しかし、これは開発者に余計な負担を負わせるものですし、そもそも開発者のレベルによっては、よくないコードの混入を完全に防ぐのは不可能です。

そこで、JavaScriptの落とし穴を検出して、エラーとして通知してくれる仕組みが導入されました。

これがStrictモードです。

Strictモードで制限される機能一覧

以下にStrictモードで通知対象となる主な構文をまとめます。

【Strictモードによる制限】
分類制限内容
変数var/let命令は省略できない
将来的に追加予定のキーワード(【表1-1】参照)を予約語に追加
引数/プロパティ名の重複を禁止
undefined NaNへの代入を禁止
命令with命令は利用できない
arguments.calleeプロパティにアクセスできない
削除できないプロパティの削除はエラー
eval命令で宣言された変数を、周囲のスコープに拡散しない
その他関数配下のthisはGlobalオブジェクトを示さない(undefinedとなる)
「0~」(古い8進法表記)は不可

表の分類「変数」の中にある「将来的に追加予定のキーワード」とは、次に掲げる表中の「*」の付いたキーワードのことをいいます。

つまり、Strictモードを利用した場合、次に掲げるキーワードを識別子(変数、クラス、関数、ラベルなどの名前)に使用した場合エラーが返されます。

【JavaScriptで意味を持つ予約語(はStrictモードの場合だけ)】【表1-1】
breakcasecatchconstcontinuedebugger
defaultdeletedoelseenumexport
extendsfalsefinallyforfunctionif
implementsimportininstanceofinterfacelet
newnullpackageprivateprotectedpublic
returnstaticsuperswitchthisthrow
truetrytypeofvarvoidwhile
withyield

Strictモードを利用するメリット

Strictモードを利用することで、JavaScriptの落とし穴を未然に防げるだけでなく、以下のようなメリットもあります。

  • 非Strictモードのコードよりも高速に動作する場合がある
  • 将来のJavaScriptで変更される点を禁止することで、今後の移行が簡単になる
  • JavaScriptの「べからず(すべきではない)」を理解する手掛かりになる

Strictモードを有効にする方法

Strictモードを有効にするには、スクリプトの先頭、もしくは、関数本体の先頭に「'use strict';」という文を追加します。(「"use strict";」でも可能です。)

スクリプトの先頭に追加する方法では以降のすべてのコードで、関数本体の先頭に追加する方法では関数配下でのみ、Strictモードが有効になります。

'use strict';
// 任意のコード

function sample() {
 'use strict';
 // 任意のコード
}

Strictモードを利用する場合の注意点

予期せぬバグをなくしつつ開発を進めることができるため、Strictモードは使いこなすととても便利です。

しかし、使用する際にはいくつか注意点があります。

スクリプトの先頭に「’use strict’」を追加する方法は原則として利用しない

スクリプトの先頭に「'use strict'」を追加する方法では以降のすべてのコードでStrictモードが有効になります。

原則として、このスクリプトの先頭に追加する方法は利用すべきではありません。

なぜなら、複数のコードを連結した場合、以降すべてのコードに影響を及ぼすためです。

非Strictモードのコードが混在している場合や外部スクリプトを読み込む場合、正しく動作できる保証はありません。

すべてのコードがStrictモードで動作していることが確認できる場合を除いて、Strictモードは、関数本体の先頭に追加する方法で有効化すべきでしょう。

Internet Explorerではバージョン10以降でしか対応していない

Strictモードは、Internet Explorerではバージョン10以降でしか対応していない点に注意が必要です。

ただし、「'use strict;'」は無害な文字列式なので、Strictモードに対応していないブラウザーでも無視されるだけです。

新規の開発では、できるだけStrictモードを有効にすることをお勧めします。

ちなみに、ES2015のモジュール、classブロックの中では、暗黙的にStrictモードが適用されるので明示的にuse strict宣言の必要はありません。

環境が許すのであれば、モジュール+クラスベースでアプリを開発していくのがモダンといえるでしょう。

Strictモードの具体例

var命令やlet命令を省略した変数を宣言した場合

たとえば関数の中で変数を宣言する際にvar命令やlet命令を省略した場合、その変数はグローバル変数とみなされます。

これは関数の外からでも変数の中身を参照できるということを意味します。

しかし、関数の中で変数を使用する場合には関数の中でのみ使用する場合がほとんどであり、また、関数の外から変数の中身を参照できることは予期せぬ値の操作等の可能性があり望ましいことではありません。

Strictモードにすることで、変数を宣言する際にvar命令やlet命令を省略した場合、エラーにすることができます。

"use strict";
function test(){
  x = 0; // グローバル変数
  console.log(x);
}
     
test();
// 結果:x is not defined

with文を使用した場合

with文は一見便利そうに見えますが、パフォーマンスが悪くなりやすく、予期せぬバグを含む可能性もあるため現在は使用することが推奨されていません。

Strictモードでは、with文がエラーになります。

"use strict";
let test = { a:123, b:"string" };

with (test) {
  console.log(a);
  console.log(b);
}
// 結果:Strict mode code may not include a with statement

予約語を変数名に使用した場合

JavaScriptではあらかじめ意味を持ったキーワードが予約語として登録されており、この予約語を識別子(変数、クラス、関数、ラベルなどの名前)に使用することはできません。

Strictモードを利用すると既に予約語として登録されているキーワード以外にも将来的に予約語に追加予定のキーワードも識別子(変数、クラス、関数、ラベルなどの名前)に使用することができなくなります。

Strictモードを有効にした場合、以下のキーワードが識別子として使用できなくなります。

【JavaScriptで意味を持つ予約語(はStrictモードの場合だけ)】
breakcasecatchconstcontinuedebugger
defaultdeletedoelseenumexport
extendsfalsefinallyforfunctionif
implementsimportininstanceofinterfacelet
newnullpackageprivateprotectedpublic
returnstaticsuperswitchthisthrow
truetrytypeofvarvoidwhile
withyield

具体例を見てみましょう。

"use strict";
let public = 1000
function test(){
  console.log(public);
}

test();
// 結果:Unexpected strict mode reserved word

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です