『Effective JavaScript』を読んで(項目4〜7)

『Effective JavaScript』を読んで(項目1~3) - hjm333のブログの続き。

 

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

JavaScript のプリミティブ値となるのは、以下の通り。それ以外はオブジェクトとなる。

  • ブール値(boolean)
  • 数値(number)
  • 文字列(strings)
  • null
  • undefined

これらをラップするオブジェクトが用意されている。例えば String オブジェクト。

var s = new String("hello");

String オブジェクトにラップすることでいくつか便利なメソッドを利用できる。気をつけなければいけないのは、オブジェクトの比較になるので組み込みの同値演算子を利用しても自身のオブジェクトと比較しないと true にならない(Java ぽい)

暗黙のラッピングにも注意する。プリミティブの strings 値に大して String オブジェクトのメソッドを呼び出そうとすると、暗黙のラッピングが行われて String オブジェクトのメソッドが利用できる。そのため、strings 値にプロパティを設定できるように見えても、暗黙のラッピングによる評価が成功しているだけで、string 値にプロパティを設定しているわけではない。

"hello".toUpperCase(); // => "HELLO"
"hello".someProperty = 17; 
"hello".someProperty; // => undefined

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

== は期待する型へ値を強制して比較を行うので注意する。例えば、以下の様なコードがtrue に評価される。

"1.0e0" == { valueOf: function () { return true; } };

上記が true となるのは、期待する型への強制が行われて、両辺共に Number 型に変換され 1となるため。

そのため、暗黙的な型変換が行われない「厳密な等価演算子(===)」を利用することが推奨される。

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

セミコロンを省略できる場合などの話。詳細は省略。Scala のコップ本にも同じような章があった。変態コーディングしたい人は覚えておく必要があるのかもしれない。

ただし、「『セミコロンつけとけば問題ないでしょ』と思っていると足下をすくわれることもある」と書かれている。いくつかの場所では改行のあとに自動的にセミコロンをいれる(return の後とか)ので気をつける。

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

Unicode との関連した話。JavaScript の strings は 16 ビットを1文字と仮定している文字列である。length や charCodeAt がその仮定に基づいている。遠い昔、Unicode が「世界中の文字を符号化するのには16ビットで十分だろ」って思ってたことに由来している。

ほとんどの場合にこの仮定で問題ないのだが、サロゲートペア(1文字を32ビットで符号化する。正確には32ビットだけじゃないかもしれない…。)が存在するので、注意が必要。「ほとんどの場合は問題ない」と書いたが、最近は絵文字がサロゲートペアを使っているので、けっこうすぐ問題になるかもしれない。

ちなみに「正しく文字列処理を行いたいなら、そういうライブラリをいれましょう」と書かれていて、自分でこういうのを実装すると大抵ミスるのでそういうことはやめた方が良い。

 

自分の語彙の少なさに辟易する・・・。あと、strings なのか string なのか調べないとだめだ。表記揺れしている気がする。

ただ、今日中に1章のメモが全部かけたのでよかった。