var p = "aiueo"; // プリミティブ型
var r = new String("aiueo"); // 参照型
通常、文字列を定義する場合はStringコンストラクタは使わずに直接記述すると思います。これはプリミティブ型でtypeof演算子で"string"と判別されます。またStringコンストラクタを使って定義すると参照型となり、typeof演算子で"object"と判別されます。
両者は同じようにプロパティへアクセスすることができ、普通に使う分には違いを感じないと思います。二つには違いはどこにあるのでしょうか。文字列を例に違いの一部を表にしてみました。
プリミティブ型 | 参照型 | |
typeof演算子(typeof(x)) | "string" | "object" |
instanceof演算子(x instanceof String) | false | true |
プロパティの定義 | 不可 | 可 |
同じ値を===演算子で比較 | true | false |
基本的なところで大きく違うことがわかると思います。この中で余り知られていないのはプロパティの定義ではないでしょうか。次のコードを実行すると、文字列にくっつけたプロパティが参照型の値では取得できますが、プリミティブ型ではundefinedとなります。
var p = "aiueo";
var r = new String("aiueo");
p.id = 100;
r.id = 200;
alert(p); // undefined
alert(r); // 200
alert(p.hasOwnProperty("id")); // false
alert(r.hasOwnProperty("id")); // true
JavaScriptでコーディングする際はこの違いを意識して書くとミスも減ると思います。最後にプリミティブ型と参照型を区別なく判定する小技と一つ。型判定はtypeof演算子やinstanceof演算子を使うのではなく、constructorプロパティで行うとプリミティブ型と参照型を区別なく判定できます。例を下記します。
var p = "aiueo";
var r = new String("aiueo");
alert(p.constructor === String); // true
alert(r.constructor === String); // true
0 件のコメント:
コメントを投稿