プリミティブ値
JavaScriptではあらゆるオブジェクトはObject型の子である。数値や文字列といったものでも例外ではない。オブジェクトはプロパティーを持ち、それは拡張できる。
var a = new Object(); a.p = "test"; alert( a.p ); // "test"
JavaScriptにはString型、Number型などがある。String型などもprototypeを持ち、そこに適用したプロパティーは文字列リテラルで生成したオブジェクトのすべてに適用できる。
String.prototype.test = "test"; a="a"; alert( a.test ); // "test"
当然、文字列リテラルで生成したオブジェクトのコンストラクタはStringである。
alert( "test".constructor == String ); // true
さて、以上をふまえて
a="a"; a.test2 = "test2" alert( a.test2 );
最後の alert は何を表示するだろうか?
なんと答は undefined である。
どうやら、JavaScript1.5では、文字列リテラルにより生成されたプリミティブ値とオブジェクトの間に区別があり、プリミティブ値はプロパティーを持つことができないのである。
ここで Stringは独自プロパティーを持つことができない、と思ってはいけない。持てないのはあくまでプリミティブ値だけである。次のようにすると、任意のプロパティーを持つStringオブジェクトを得ることができるのだ。
a=new String("test"); a.test2 = "test2" alert( a.test2 ); // "test2"
さてこのオブジェクトをtypeof演算子で調べてみよう。
alert( typeof "test" );
は当然 "string" であるが、
alert( typeof new String("test") );
とすると "object" と出る。
比較演算子に、この違いが影響する。
(new String("test"))==(new String("test"))
この演算の答はなんと、false となるのである。さらに言うと、
(new String("test"))=="test"
この演算は、Firefoxでは true 、IE では falseとなる。
うーん、new String("test") は多くの場合 "test" と同じ動作をするのであるが…