strict modeとは何か
非ES ModulesのJavaScriptでは、ファイルの先頭や関数の先頭に"use strict"
という記述を行うことで、strict modeが有効になります。
function log(val) {
"use strict";
console.log(val)
}
このstrict modeは以下のような効果があります。
- 存在しない変数への代入をエラーとして扱う
- with文の削除
- 8進数表記を禁止
- 予約語の追加
- eval内で宣言した変数のスコープ
- などなど
strict modeは、後方互換性のために排除できなかった、挙動に問題がある構文を排除し、将来の言語の拡張や動作の高速化に対応するものです。
(たまに後方互換性を排除してJavaScriptをイチから作り直してほしいという人がいますが、strict modeが実質それだと考えられます。)
このstrict modeですが、ES Modulesではデフォルトで有効になっています。
Deno と ES Modules と strict mode
Denoでは全てのコードがES Modulesとして実行されます。
ES Modulesの場合、全てのコードがstrict modeとして実行されます。
モジュール内部で定義されたスクリプトの動作は、通常のスクリプト内部のものと異なるかもしれません。これは、モジュール内部では自動的に Strict モード が使われるからです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Modules#other_differences_between_modules_and_standard_scripts
よって、Denoで動作するコードは全てstrict mode扱いになります。
function log(val) {
// "use strict"が無くても自動的にstrict modeになる
console.log(val)
}
このため、Denoでは非strict modeで使えていたwith文などの古い構文を使うことができません。
TypeScript の strict オプションもデフォルトで有効
TypeScriptにもstrictオプションが存在します。TypeScriptのstrictオプションはstrict modeとは別物なので注意してください。
TypeScriptのstrictオプションは型チェックを厳格にするものです。
公式マニュアルによると、Denoではstrictオプションがデフォルトで有効になっています。
これを無効化するには、deno.jsonかtscofig.jsonに設定を記述した上で、実行時にコマンドライン引数で渡します。
{
"compilerOptions": {
"strict": false // デフォルトではtrue
}
}
> deno run --config ./tsconfig.json main.ts
tsconfigのオプションはライブラリを含め、コード全体に適用されることに注意してください。 例えば「実験的なデコレータ」(experimentalDecoratorsオプション)を有効にした上でライブラリを作成してしまうと、そのライブラリのユーザーは全てのコードをexperimentalDecoratorsオプション付きで実行する必要があります。 一方で、「実験的なデコレータ」の代わりに「ES標準デコレータ」というものが数年後に導入される予定があります。使用しているライブラリの中に一つでもexperimentalDecoratorsが含まれる場合、他のライブラリがES標準デコレータを使うことができなくなるため、ES標準デコレータへのアップデートが妨げられます。 カスタムのtsconfigを使用する場合、このような将来的な後方互換性問題が発生する可能性が高く、それなりの覚悟が必要です。
まとめ
- Denoは全てのコードをstrict modeで実行する
- TypeScript の strict オプションもデフォルトで有効になっている