下記コードは、私には同じことをしているように見えるのですが、
Aの方じゃないと駄目なケース、
Bの方じゃないと駄目なケースというのは存在しますか?
それともAとBは完全に、お互いを代替え可能なものでしょうか?
//-----------------------------------------------
// A
//-----------------------------------------------
var Box = {
a: 1
}
console.debug( Box.a );// 1
//-----------------------------------------------
// B
//-----------------------------------------------
function Box()
{
this.a = 1;
}
var hoge = new Box;
console.debug( hoge.a );// 1
No.2ベストアンサー
- 回答日時:
一応、私なりの回答をしますが、もっと詳しい人が回答するかもしれないので、しばらくオープンにされたほうがいいと思います(というか私も知りたい^^;)。
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の方法でいいと思います。
ありがとうございます。
下記の箇所を見て思い当たりました。
なるほど。そういえばそうですね。
newするだけで識別できますね。
---------------------------------
Bならば、
var hoge = new Box;
var fuga = new Box;
で済みますが、Aの場合、
var Box2 = Box;
---------------------------------
prototypeの部分もryu_chanさんがきっかけで何かかが分かりかけている気がします。
とても勉強になりました。
もう少しコードを試せばprototypeがわかりそうかもです??
No.3
- 回答日時:
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の存在は知っていましたが、今使うのか!と教えられてやっと気づいた次第です。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ローカルのレジストリを読みたい
-
タブブラウザで focus() を実...
-
「終了していない文字列型の定...
-
1つのVBAコードをすべてのコア...
-
JSPの処理の途中で、JavaScript...
-
gas 全角数字を半角数字に変換
-
contenteditableで編集した内容...
-
jQuery ui Datepicker 明日以降...
-
ページ遷移時にアコーディオン...
-
JavaScriptで ブラウザの閉じる...
-
csvファイルを読み込み、該当項...
-
PDFフォームで条件つき金額を表...
-
CGIとJavascriptの違いについて
-
javascriptで「オブジェクトを...
-
javascriptからサーバサイドの...
-
ASP(VBS) ←→ JavaScript の変数...
-
エラーが表示される
-
1回のクリックで2回違うイベント
-
JavaScriptの負荷について
-
javascriptでsjisの文字列からu...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ローカルのレジストリを読みたい
-
Webページ中の javascript をVB...
-
Shell.ApplicationでのIEオブ...
-
エクセル2010のvbaについて
-
イベントevt?evt.target:event....
-
フォルダ内のファイル名を取得...
-
タブブラウザで focus() を実...
-
evtとは
-
event.srcElementの動的設定
-
jQuery for内にある配列の後の...
-
画面間でのJavaScrip...
-
チェックボックスを認識・不認...
-
JavaScriptで複数のプロパティ...
-
Dateオブジェクトの大小比較の...
-
for...inのプロパティ取り出し...
-
CSSのクラスを動的に変更 classで
-
javaScriptでグローバル変数に...
-
イベントリスナに登録される fu...
-
IEでDOMインターフェースを拡張...
-
文字を移動させその位置を表示...
おすすめ情報