strictモードは、JavaScriptを頑固おやじモードにする。具体的には、ナァナァで許されていた一部の記述が許されなくなる。

strictモードとsloppyモード

strictモードは、JavaScriptをより安全かつクリーンに動作させるために、ECMAScript5から導入された。ちなみに、’strict’は’厳しい’とか’厳密な’という意味の英単語である。

これに対して、sloppyモードというモードもある。これは、strictモードではないJavaScriptの別称である。つまり普通のJavaScriptだ。’sloppy’は、’ルーズな’とか’いい加減な’という意味を持つ。言い過ぎな気もするが、JavaScriptの愛らしさを見事に捉えているような気もする。

使い方

strictモードへの切り替えは、以下のいずれかの一行目に、"use strict;"という文字列を記述することで行う。

  • ファイル(※モジュールの場合は明示しなくともstrictモードで動作する)
  • クラス
  • 関数
  • <script>タグ

つまり、記述する位置によって、strictモードの適用範囲を絞れる。一般的には、ファイルの頭に記述することが多い。

ちなみに"use strict;"のように、ファイルや関数、<script>タグの最初の行に置かれる文字列リテラルは、ディレクティブプロローグと呼ばれるらしい。

現状では、公式っぽいディレクティブプロローグは"use strict;"しか見つけられなかった。Next.jsの"use client";とか"use server";はこれを模したもの、あるいは利用したものではないかと思う。わかったら追記したい。

制限の内容

strictモードを有効にすると、該当の範囲のコードに対して以下のような制限が課される。

  • implementsinterfaceletpackageprivateprotectedpublicstaticyieldが予約語として判断される。
  • 0で始まる数値リテラルを許さない(8進数リテラルを使う場合は0oまたは0Oで始める)。
  • 宣言されていない変数やプロパティへの代入を許さない(参照エラー、型エラーが投げられる)。
  • evalargumentsを、代入演算子の左辺に使ってインクリメント、デクリメントできない。
  • arguments.calleeにアクセスすると型エラーが投げられる。
  • 関数内で引数に別の値を代入しても、argumentsの中身を更新しない。
  • argumentsを更新できない。
  • evalargumentsを変数として使うと構文エラーが投げられる。
  • eval()内で外部変数・関数を参照はできるが、上書きしても外には影響しない。
  • グローバル直下の関数のthiswindowにせず、undefinedにする(call()apply()で明示することを強制する)。
  • delete演算子によって直接的な変数や関数の引数、関数名の削除を行うと、構文エラーが投げられる。
  • delete演算子によって削除不可のプロパティの削除を行うと構文エラーが投げられる。
  • with文を使うと構文エラーが投げられる。
  • catch()のパラメータ名にevalあるいはargumentsを使うと構文エラーが投げられる。
  • 重複した引数名を使うと、構文エラーが投げられる。
  • 関数インスタンスのプロパティとしてcallerargumentsにアクセスできない。

上記は、このページの内容を、Chat-GPTとDeepLと私のあやしい英語力を駆使して意訳したものである。トークン名が多く紛れていてよくわからない部分があった。というか独力で読んだだけでは大部分がチンプンカンプンだった。間違っていても知らないよ。

と思ったらMDNに綺麗にまとめられてた。初めからこっち読めばよかった。TOHOHO〜T。

使用上の注意

"use strict";をスクリプト全体に適用すると、グローバルスコープに影響が及ぶ。これによって、既存のプログラムが動かなくなる可能性がある。

サードバーティライブラリを利用する場合は、互換性を確認することが重要である。

解除方法

strictモードは任意に解除できない。部分的に適用したい場合は、先の有効範囲に基づいて"use strict";を指定し直すしかない。

どう使うべきか

最終的には、すべてのコードにstrictモードを適用するのが望ましい。より安全で読みやすいJavaScriptコードを目指して導入されたのだから当然と言えば当然である。

ただ、既存のコードとの兼ね合いもあり、無理くり強制するのはあんまりだ。というわけでstrictモードは段階的に適用できるように設計されている。

まずは関数などの小さな単位から始めて、徐々にエラーを取り除き、コードベース全体をstrictモードに切り替えていくことが推奨される。

参考資料