2つのデータ型
唐突ですがこの2つの違いが分かりますか?
var a = "abc";
var b = new String("abc");
下記のコードを実行すると、何かが異なりそうだということが分かります。
var a = "abc";
var b = new String("abc");
alert(typeof a);
alert(typeof b);
aは「string」と評価され、bは「object」と評価されます。これはaに代入している「"abc"」という値はstringのプリミティブ型であり、bに代入している「new String("abc")」で生成される値はオブジェクト型であることを示しています。
オブジェクトとプリミティブ型の違い
JavaScriptには大きく分けてオブジェクト型とプリミティブ型の2つのデータ型があります。両者の違いはあまり意識されることはありませんが、実は大きな違いがあります。オブジェクト型は値のほかに、さまざまなプロパティやメソッドを持つことができます。一方でプリミティブ型は値のみを持ち、プロパティやメソッドを持つことができません。こう書くと『プリミティブ型と呼んでいるものでも、プロパティやメソッドにアクセスできるじゃないか』と思われる方もいらっしゃるかも知れません。
例えば以下のように。
var a = "abc";
alert(a.length);
しかしプリミティブ型に対しプロパティの参照やメソッドの呼び出しがあった場合には、以下のように一時的・暗黙的にオブジェクト型に変換されているのです。
var a = "abc";
alert((new String(a)).length);
このことは以下のコードで確かめることができます。
String.prototype.name = "no name";
var b = new String("abc");
b.name = "name is b";
alert(b.name);
これは「"name is a"」になります。
String.prototype.name = "no name";
var a = "abc";
a.name = "name is a";
alert(a.name);
これは「"no name"」になります。
つまりこちらは内部的に以下のコードに変換されているのです。
String.prototype.name = "none";
var a = "123";
(new String(a)).name = "name is a";
alert((new String(a)).name);
stringのnameというプロパティに値を代入(しようと)すると、エラーは出ないもののアクセスするたびに新しいオブジェクトを生成する為、値を保持することができないのです。
プリミティブ型とオブジェクト型は混同してしまいがちです。多くの場合、区別できなくても困ることはないと思います。しかし多くの経験を重ねれば、いつかこのようなコードに遭遇するかもしれません。そのときに十分な理解ができていなければ「なんかよくわかんない、バグじゃないの?」などと間違った判断をしかねません。プロのSEならばきちんと理解し、区別できるようになっておきたいところです。
2012/01/08
|