- ベストアンサー
jsのオブジェクトに関する疑問とは?
- jsのオブジェクトに関する疑問です。AとBのコードが同じことをしているように見えますが、Aの方とBの方で使い方に制約があるのでしょうか?また、AとBは完全に代替え可能なのでしょうか?
- AとBのコードは、jsのオブジェクトに関する疑問を表しています。見た目では同じように見えますが、AとBは使い方によって制約があるのか、お互いを代替え可能なのかについて知りたいです。
- jsのオブジェクトに関する疑問です。AとBのコードは同じように見えますが、Aの利用方法とBの利用方法に制約があるのか、またAとBは完全に代替え可能なのかについて教えてください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
一応、私なりの回答をしますが、もっと詳しい人が回答するかもしれないので、しばらくオープンにされたほうがいいと思います(というか私も知りたい^^;)。 Aの var Box = { a: 1 } は、 var Box = (function() { var obj = new Object; obj.a = 1; return obj; })(); と、ほぼ等価なので、コンストラクターにObjectを使ってることになります。 Bの場合は、明示してある通りBoxがコンストラクターになります。 なので、生成されたインスタンス(オブジェクト)の[[prototype]]プロパティ(__proto__)が異なります。 もちろん、コンストラクターが違うので、constructorプロパティも異なります。 [Aの場合] Box.__proto__ === Object.prototype Box.constructor === function Object [Bの場合] hoge.__proto__ === Box.prototype hoge.constructor === function Box プロトタイプチェーンを利用して、静的プロパティを定義するとき、Bならば Box.prototype.method = function(){ hogehoge... }; となりますが、Aの場合は、 Object.prototype.method = function(){ hogehoge... }; と、全てのオブジェクトの大元であるObjectにプロパティを定義することになり危険です。 それから、No.1のbabu_babooさんもおっしゃってますが、似たオブジェクトを複数生成する場合、Bならば、 var hoge = new Box; var fuga = new Box; で済みますが、Aの場合、 var Box2 = Box; では、オブジェクトの参照先(アドレス)をコピーしているだけとなり、新たなオブジェクトの生成にはなりません。 新たな類似オブジェクトの生成には、deep copyが必要となりますが、JavaScriptではかなり困難です。 以上より、私なりの結論としましては、静的プロパティ(プロトタイプチェーン)を利用せず、その1つだけのオブジェクトの生成だけでいいときは、表記が簡単でわかりやすいAの方法でいいと思います。
その他の回答 (2)
- Chaire
- ベストアンサー率60% (79/130)
instanceof の結果が違います。 // A Box instanceof Box; // TypeError Box instanceof Object; // true // B hoge instanceof Box; // true hoge instanceof Object; // true new を使うと、そのオブジェクトがどのコンストラクタから作られたものか、という情報が残ります(正確には、どのオブジェクトにプロトタイプ委譲しているか)。 例えば、XPath パーサを書くとします。まず大元となる XPathObject を用意し、そこから派生した XPathString、XPathNumber、XPathBoolean、XPathNodeSet を作ります。 このとき、あるオブジェクト obj がどのデータ(文字列、数値、真偽値、ノードセット)であるかは instanceof を使えば分かります。仮に、 var sequence = [obj1, obj2, obj3]; というシーケンスがあり、ここから数値であるものだけ取り出したい、というときは var numOnly = sequence.filter(function(obj) { return obj instanceof XPathNumber; }); のようにすれば良い。 データ・オブジェクト設計をうまくやれば instanceof を活用できるし、ひとつのオブジェクトにゴチャゴチャ詰め込むなら活用できない。その程度と言えばその程度の話です。 --- なお、No.2 の仰る『deep copy』に関しては、ECMAScript 5 / JavaScript 1.8.5 で Object.create() が導入されましたので、 // A' var box_ = Object.create(Box); で Box にプロトタイプ委譲する box_ を作ることができます。deep copy とはやや(かなり)異なりますが、ある意味ではこれが(__proto__ に近い)素直なプロトタイプベースですね。 さらに、同じく ECMAScript 5 で導入された Function#bind() を使えば // B' var huga = new Box.bind.apply(Box, arguments); のように、new するコンストラクタに任意数の引数を渡すことができます。この辺で悩んだことのある人には朗報でしょう。 これらはそれぞれ A、B に関わる拡張です。つまり、どちらも(それなりに)必要ということです。そして、両者はともに instanceof が自然な結果になるよう考えられています。
お礼
反応が遅れましたが、僕の知らないことがたくさん紹介されていてとても啓発を受けました。 理解するのにいろいろ調べる必要がありそうなので、先にお礼を述べさせていただきます。 instanceofの存在は知っていましたが、今使うのか!と教えられてやっと気づいた次第です。 ありがとうございました。
- babu_baboo
- ベストアンサー率51% (268/525)
そのうち、まっとうなかいとうがあるでしょう~! >私には同じことをしているように見える わたしにもそうみえる。^^; >Aの方じゃないと駄目なケース きのうを1つにまとめるときに、べんり。けっして、だめというほどでもないけれど。 >Bの方じゃないと駄目なケース それをふくすうひつようとするばあい。
お礼
ありがとうございます。 ケースバイケースという感じでしょうか。 あまり重要な問題でもないのかもしれないですね?
お礼
ありがとうございます。 下記の箇所を見て思い当たりました。 なるほど。そういえばそうですね。 newするだけで識別できますね。 --------------------------------- Bならば、 var hoge = new Box; var fuga = new Box; で済みますが、Aの場合、 var Box2 = Box; --------------------------------- prototypeの部分もryu_chanさんがきっかけで何かかが分かりかけている気がします。 とても勉強になりました。 もう少しコードを試せばprototypeがわかりそうかもです??