こんにちは
EffectiveJavaScriptの翻訳版が発売されて社内で「磯野ー!読書会やろーぜ!」といってしまった手前、しょっぱに書かせてもらいます。
まずは最初の最初である項目1について解説をば。
JavaScriptの経緯
最初はJavaScriptの歴史について軽く書かれていました。ECMAScriptの話ですね。
ECMAScriptは簡単に言ってしまえば、JavaScriptの標準規格(最低○○の動作や仕様は保証してね)というものです。
で、現在は第3版(ES3)と第5版(ES5)が広く普及しているようです。第4版についてはいろいろごたごたがあって標準化が出来ずに終わっています。詳しくは自分で調べるといいと思います。
また本書にはかかれてなかったですが最近では第6版の策定が進められていてなかなか面白い仕様が増えるようですよ奥さん!
ちなみに本書ではES5にフォーカスしていろいろ書かれているようです。
非標準機能
上で述べたようにJavaScriptはECMAScriptで標準規格が定まっていますが、逆に言えば「これさえ守っておけば後は独自拡張してもええよ」ということになります。具体的に言うとブラウザごとに動いたり動かなかったりする機能や仕様が存在したりします。
本書で挙げられている例ではconstが挙げられています。
(余談ですがconstについてはECMAScript第6版の標準仕様に盛り込まれる予定らしいです。)
たとえば次のコードではどういう結果を望むでしょうか。
const x=1;
console.log(x);
x=10;
console.log(x);
constで宣言されているためxの値が変わらないことを期待するでしょう。実際のそのとおりに動くものもあります。が、動かないものもあります。(実際に手元のブラウザで確認しましたがChrome,Firefoxは期待通りに動いてIEではsyntax errorを出しました)
'use strict'を使おう
こういうのはわかっていてもついつい使ってしまうことがままあるかと思われます。しかしながら複数ブラウザ対応しなくてはいけないのが、web開発においては重要なので、出来るだけわかりやすく警告してくれると助かります。そういうときには'use strict'をコードの先頭に書けば非標準の仕様の利用を禁止することが出来ます。
たとえばグローバル変数宣言をしてしまった場合にエラーを出します。
"use strict";
var x=10;
y=5; //ReferenceError: assignment to undeclared variable y
strictモード時にどういうものが禁止になるかは下記を参照してください
https://developer.mozilla.org/ja/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode
なぜ文字列リテラルを使うかというと後方互換性を保つためです。文字列リテラルなら
ES5よりも古いものだったとしても実行可能だからです。この場合ちゃんとES5環境にしてくれよ!と思うかもしれませんが大人の事情とかもあるかもしれないので、それはまた別の話です・・・。
strictモードの注意点
strictコードはモダンなJavaScriptを書くときにはほぼ必須といいレベルで書くべきだと思われます。しかし使う場合にもさまざまな問題があります。
strictモードの最大の問題は「"use strict"ディレクティブは必ずそのスコープの先頭におかなくてはならない」ということです。
ぱっと見「そんなの当たり前じゃないか。忘れるわけないよ!」と思うかもしれませんが、規模が大きくなったときにこの問題は顕著になってきます。
JavaScriptではファイル単位でのモジュール機構をデフォルトでは備えていないため最初に読み出されるプログラムファイルの先頭に"use strict"が存在すれば、以下に読み出されるプログラムファイルにも適用されてしまいます。
また逆に"use strict"が最初に読み出されるプログラムファイルがなければstrictモードにはならないということです。
これの問題の解決方法としては即時関数式を用いてスコープを制御する方法があります。
たとえば以下のコードでは上の部分ではstrictモードになっていますが、下の部分ではstrictモードにはなっていません
(function(){
"use strict";
var x=10;
y=5; //ReferenceError: assignment to undeclared variable y
})();
(function(){
var a=10;
b=5; //ok
})();
この考え方はモジュール機構と同様の方式です。
このようにしておけば既存コードを保持しつつ、新規部分についてはstrictモードを使ったモダンなJavaScriptを書くことが出来るということです。
ということで長い事欠きましたが第1項を読んだまとめでした。
次回もご期待ください!
(あるかわからないけど)