モダンJavaScript:データ処理とコード設計
strict mode が先に教えてくれる間違い
この回でやること
JavaScript を厳しい判定モードで動かす仕組みです。黙って通っていた書き間違いがエラーとして表面化するので、原因を探す時間が短くなります。
- 読む 約 15 分
このレッスンで分かること
- ファイルの先頭に
"use strict";と書くと、黙って見逃されていた間違いがその場でエラーになります- 打ち間違えた変数名が勝手にグローバル変数になる事故を止められます
合計が 0 になるのに、エラーは 1 行も出ない
作品の表示回数を合計する関数です。よく見ると 1 か所だけ打ち間違いがあります。
JavaScript
function sumViews(works) {
let total = 0;
for (const work of works) {
totla = totla + work.views;
}
return total;
}total と書くべきところが totla になっています。それでもこのコードはエラーになりません。実行すると 0 が返ってきます。JavaScript は totla を「まだ宣言されていない変数への代入」と見なし、勝手にグローバル変数を作って代入するからです。合計は totla のほうに溜まり、total は 0 のまま返されます。
合計は 0 のまま画面に出ます。数字が合わないという症状だけがあって、どこが壊れているのか手がかりがありません。ここで、ファイルの先頭に 1 行足します。
JavaScript
"use strict";今度は実行した瞬間に ReferenceError が出ます。しかもコンソールには totla is not defined と、打ち間違えた名前がそのまま表示されます。探す手間はゼロになりました。
何が止まるようになるのか
strict mode は新しい機能を足すものではありません。JavaScript が昔の互換性のために見逃していた書きかたを、見逃さないようにするだけです。動くコードが動かなくなるのではなく、壊れているコードが壊れていると分かるようになります。
| 書きかた | ふつうのモード | strict mode |
|---|---|---|
| 宣言していない変数への代入 | グローバル変数が作られる | ReferenceError |
const で作った値への再代入 | 黙って無視される場合がある | TypeError |
引数名の重複 function f(a, a) | 後ろの a が勝つ | SyntaxError |
関数を単体で呼んだときの this | window を指す | undefined |
引数名の重複は、書いているときに気付きにくい割に厄介です。2 つ受け取っているつもりなのに、実際には後ろの値しか使えません。呼び出し側は 2 つ渡したつもりでいるので、表示だけが静かにずれます。
4 つに共通しているのは、どれも 黙って間違った値が返る という点です。増えたエラーの分だけ、原因を探す時間が減ります。
先頭に置かないと効かない
"use strict"; は、ファイルまたは関数の いちばん先頭 に置く必要があります。前にコメントがあるのは構いませんが、文が 1 つでも先にあると、ただの文字列として無視されます。エラーも警告も出ないので、効いていないことに気付けません。
JavaScript
// 誤り。const の後ろに書いても効かない
const works = [];
"use strict";
totla = 1; // エラーにならない
// 正しい。先頭に置く
"use strict";
const works = [];このコースでは app.js の先頭に 1 行だけ置く形をとります。入門から let と const だけを使い、宣言してから使う書きかたを守ってきたので、足してもほとんどのコードはそのまま通ります。
よくある間違い
- クォートを付け忘れる —
use strict;と書くと、useという変数を参照するだけの式になります。文字列として書かなければ何も起きません - エラーが増えたので外してしまう — strict mode にした直後は、それまで隠れていた不具合が一気に表に出ます。増えたのはエラーであって不具合ではありません。1 つずつ潰すほうが、黙って間違った値が表示され続ける状態よりも短時間で終わります