- ベストアンサー
javascriptのObject()コンストラクタについて質問です。
- JavaScriptのObject()コンストラクタについて質問です。Object()コンストラクタを使用してオブジェクトを作る際に、new演算子は必要ありませんか?また、new演算子を使用しない場合と使用した場合のオブジェクトの違いは何でしょうか?
- 質問者は、どこかのサイトでObject()コンストラクタとnew演算子の使い方に関する記事を読んだような気がしています。Object()コンストラクタを使用する際にnew演算子の使用の有無は問題ありません。new演算子を使用しない場合と使用した場合のオブジェクトに違いはありません。
- 質問者はobjとobj2の2つのオブジェクトの違いを試してみましたが分からないとのことです。new演算子を使用したインスタンスと使用しないインスタンスの違いは特にありません。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ANo.4について少し分かりにくかったかもしれないので、一応補足しておきます。 newなしはnewありの省略形ではないです。newなしなら普通の関数、newありならコンストラクタとして動作します。 JavaScriptの標準オブジェクトの中には普通の関数とコンストラクタとで同じ動作をするものもあれば、違う動作をするものもあります。Function型じゃないものも存在します。いろいろあるので、どのように動作するかはリファレンスを参照するのが確実です。 最後に書いたStringについてですが、プリミティブ型の比較は値の比較になるので、別で生成されたオブジェクトかどうか(参照比較)は判別できないので気をつけてねって言う意味です。 おまけです。 以下のようなfunctionにすると、コンストラクタとしても普通の関数としても機能させることができます。 両者で同じ動作をする例です。 var Foo = function() { var Self = arguments.callee; // …1 if (!(this instanceof Self)) { // …2 return new Self(); // …3 } this.prop1 = 'prop1'; // …4 }; 1. arguments.calleeはfunction内で自身のfunctionへの参照値を持つプロパティです。 2. コンストラクタのときはthisがインスタンスへの参照になるので、この条件分岐は「thisがこのfunction自身のインスタンスではない」なら普通の関数である … ということを行っています。 3. ここは普通の関数のときに実行されます。関数自身をコンストラクタとして起動して、インスタンスを返します。 ちなみにコンストラクタのときはreturn文実行してもその値ではなく、インスタンスが返ってきます。そのときreturn文は実行されることには変わらないので、2の条件分岐がないと無限ループになる上に、4でグローバル変数を作ってしまいます。 4. それ以降の文はコンストラクタのときのみ実行されます。 3で他の値を返すようにすれば、普通の関数とコンストラクタとで別の動きををさせることができます。
その他の回答 (4)
- imq
- ベストアンサー率72% (16/22)
そんなに難しく考えなくてもいいですよ。 JavaScriptはコンストラクタも関数も同じFunctionなので、どちらとしても動かせることができるというだけのことです。 つまり、 ↓はObject型のインスタンスを生成します。 new Object(); ↓はオブジェクトを返す関数です。 Object(); ANo.3でのStringについては、 ↓はStringオブジェクト型のインスタンスを生成します。 new String(); ↓は文字列を返す関数です。 String(); *ちなみStringオブジェクトと文字列は殆ど似たような動作をしますが、Stringは参照型で文字列はプリミティブ型というJavaScriptの変態仕様があるので、ちょっと注意が必要です。 console.log(new String('a') == new String('a')); // false console.log(String('a') == String('a')); // true コンストラクタと関数、どちらとしても動くFunctionを自分で作ることもできます。
お礼
ご回答ありがとうございます。 データ型の知識不足でご回答の内容を理解するのに 時間がかかってしまいました。 Object()はオブジェクトを返す単なる関数ということで、 あまり深く考えないようにします! しかし最後の「コンストラクタと関数、どちらとしても動く Functionを自分で作ることもできます。」 これがまた気になってしまって、、、 頑張って考えてみたいと思います(笑) 前回共にどうもありがとうございました!!
- 15mm
- ベストアンサー率65% (65/100)
var obj2 = Object();の使い方がコンストラクタなのか、内部処理は知りません。 私の解釈では、 ・new classA(args...) はclassAのインスタンスを生成(コンストラクタ) ・classA(B) はBをclassAの型に変換する です。パッと思いつくのでは、1+Number("1")とかいう変換。newあっても同じですが・・・ さて、本題(IEで検証中)。 >どこかのサイトでこの2つは等価みたいな記事を読んだような気がするのですが そんなわけないです。たとえまったく同じ構造のオブジェクトを作ったとしても ({x:1,y:2})===({x:1,y:2})//false メモリ内での参照先が違えば===はfalseを返すと思います。(プリミティブ型は別問題。1===1、"a"==="a") >Objectコンストラクタでオブジェクトを作る際はnew演算子は要らない? 上記のとおり、コンストラクタを呼び出したいのか、変換をしたいのか、それによる。 でもjavascriptは型に厳密なほうじゃないので、あまり関係ないかも。 (私はactionscript3.0で差を実感) newつけたほうがコードとしての見栄えはよくなるし、 共同制作なんて時の為にもnewを付ける癖はあってよいと思います。 (「初期化子」便利ですよー なんて言ってみる) >2つの違いを色々試したのですが違いがわかりません objectはすべての元となる型だから、例を変えますね。 var str1=new String("a")//Stringのオブジェクトを生成(コンストラクタの引数:"a") var str2=String("a")//文字列"a"をString型に変換 alert([typeof(str1),str1 instanceof String])//object,true あくまでStringオブジェクト alert([typeof(str2),str2 instanceof String])//string,false newでコンストラクタを呼ばないとinstanceにはならない alert(str1===str2)//型が違うのでfalse でも、それがどうした・・・?(自問) たぶん、オブジェクトの生成方法(内部処理)が違うのでしょう。 typeof(Object)が"function"なんですから。(意味が違うかも) 不十分さが拭えませんが、結論。 Object()がそれっぽいものを作る関数で、new Object()がinstanceを作る正規のコンストラクタ。 Date()なんて、文字列を返す関数でしかない(笑) 引数も受け付けてくれないし。 actionscriptとイメージ違うな・・・
お礼
ご回答ありがとうございました。 データ型の知識不足でご回答をいただきました内容を 理解するのに時間がかかってしまいました。 Object()はオブジェクトを返す関数ということで、 なんとなくわかってきた気がします! どうもありがとうございました。
- fujillin
- ベストアンサー率61% (1594/2576)
よくわかっていないのですが… newを使うもんだとばかり思っていたので、ちょいと実験してみました。 var obj = new Object(); var obj2 = Object(); var obj3 = {}; alert(obj.constructor); alert(obj2.constructor); alert(obj3.constructor); Object.prototype.hoge = 'fuga'; alert(obj.hoge); alert(obj2.hoge); alert(obj3.hoge); obj、obj2、obj3ともに同じ結果を返しますね。 確信はないけれど、等価のような気がしてきた…
お礼
ご回答ありがとうございました。 ObjectやArrayは確かにnewを使用しなくても 問題なくオブジェクトが作れそうですね。 ご回答ありがとうございました。
- DOUGLAS_
- ベストアンサー率74% (397/534)
私は、全く興味がありませんので、読んでみても何の事やらさっぱり理解できないのですが、下記がご参考にならないでしょうか? ●オブジェクト指向の手法によって高度な Web アプリケーションを作成する http://msdn.microsoft.com/ja-jp/magazine/cc163419.aspx >類似のオブジェクトを作成することが必要なときには、“new” を指定してコンストラクタ関数を呼び出すことで、完全に初期化されたオブジェクトを取得できます。
お礼
ご回答いただきありがとうございます。 リンク先をじっくり読ませていただきます。 ありがとうございました。
お礼
ありがとうございます! コンストラクタとしても普通の関数としても使える関数について すっきりしました! ご丁寧な回答大変感謝いたします。