kidoOooOoooOOom

IT系で開発やってます

Effective JavaSceipt 読書メモ 項目4~7

第1章 JavaScriptに慣れ親しむ

項目4 オブジェクトラッパーよりもプリミティブが好ましい

例えばstringのプリミティブ型の比較では同値として比較できるが、

console.log("hello" === "hello"); // true

Stringオブジェクトにすると、別のオブジェクトとして扱われるため比較演算子が期待通りの動きにならない。

var s1 = new String("hello");
var s2 = new String("hello");
console.log(s1 === s2); // false
console.log(s1 == s2); // false

プリミティブ値に対してStringオブジェクトのプロパティやメソッドを呼び出すと、JSが「暗黙の強制」を行い、期待通りの結果が得られる。

console.log("hello".toUpperCase()); // HELLO

項目5 型が異なるときに==を使わない

下記のような式の結果は、暗黙の強制により同値として扱われてしまう

console.log("1.0e0" == { valueOf: function() { return true; } }); // true

== 演算子は、引数の型が異なるとき、データ表現の違いをなんとかごまかして包み隠そうとする。
=== は厳密な同値演算子であり、比較に暗黙の強制が関わらないないことをハッキリ示すことができる。
よって、暗黙の強制があまりにも明示的な時以外では、===を使うべきである。

項目6 セミコロン挿入の限度を学ぼう

結論としてはセミコロン自動挿入を期待してはいけないということ(JShintでも警告でる)。
まず、セミコロン挿入の第1ルールは下記の通り。

セミコロンが挿入されるのは、"}"トークンの前か、1個以上の改行の後か、プログラム入力の末尾だけである
よって次の例は違法となる。

function area(r) { r = +r return Math.PI * r * r } // error

セミコロン挿入の第2ルールは下記の通り。

セミコロンが挿入されるのは、次の入力トークンを字句解析できないときだけである

これは処理の順番によって挿入されるケースとされないケースが分かりにくいため注意が必要。
例えば下記の2つのケースでは、処理は同じ3つの文だが、セミコロン挿入によって異なる挙動になる。

a = b // セミコロンが推論される
var x // セミコロンが推論される
(f()) // セミコロンが推論される
var x // セミコロンが推論される
a = b // セミコロンが推論されない!!
(f()) // セミコロンが推論される

3つ目のルールは、

セミコロンが、forループ頭部の区切りとして、あるいは空文として、挿入されることは決して無い

つまり、下記はエラーになる

for ( var i = 0, total = 1 // parse error
        i < n
        i+) {
      }

項目7 文字列は16ビットの符号単位を並べたシーケンスとして考えよう

JavaScript文字列の要素は16ビットの符号単位である 

ということが重要。
例えば、UTF-16においては、𝄞 (ト音記号)は 0xd834 と 0xddle の1対の符号単位で表現される。
これに対し、Javascriptでlengthを調査すると、

console.log("𝄞".length); // 2 

2を表示してしまう。

このことを意識することは非常に労力がいるため、符号位置を意識する文字列操作を書くには、できるだけサードパーティーのライブラリを使ったほうが良い。