プロが教えるわが家の防犯対策術!

javascriptのObject()コンストラクタについて質問です。

var obj = new Object();
var obj2 = Object();

console.log(obj === obj2)//false

いつも質問ばかり恐縮です。。。
どこかのサイトでこの2つは等価みたいな記事を読んだような気がするのですが、
ということはObjectコンストラクタでオブジェクトを作る際はnew演算子は要らない??
のでしょうか??
またobjとobj2の2つの違いを色々試したのですが違いがわかりません。new演算子を
付けたインスタンスと付けないインスタンス??の違いをどなたか
ご教授いただけると助かります。

A 回答 (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で他の値を返すようにすれば、普通の関数とコンストラクタとで別の動きををさせることができます。
    • good
    • 0
この回答へのお礼

ありがとうございます!
コンストラクタとしても普通の関数としても使える関数について
すっきりしました!
ご丁寧な回答大変感謝いたします。

お礼日時:2010/05/14 04:45

そんなに難しく考えなくてもいいですよ。


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を自分で作ることもできます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
データ型の知識不足でご回答の内容を理解するのに
時間がかかってしまいました。
Object()はオブジェクトを返す単なる関数ということで、
あまり深く考えないようにします!
しかし最後の「コンストラクタと関数、どちらとしても動く
Functionを自分で作ることもできます。」
これがまた気になってしまって、、、
頑張って考えてみたいと思います(笑)
前回共にどうもありがとうございました!!

お礼日時:2010/04/30 00:59

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とイメージ違うな・・・
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
データ型の知識不足でご回答をいただきました内容を
理解するのに時間がかかってしまいました。
Object()はオブジェクトを返す関数ということで、
なんとなくわかってきた気がします!
どうもありがとうございました。

お礼日時:2010/04/30 00:47

よくわかっていないのですが…



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ともに同じ結果を返しますね。
確信はないけれど、等価のような気がしてきた…
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
ObjectやArrayは確かにnewを使用しなくても
問題なくオブジェクトが作れそうですね。
ご回答ありがとうございました。

お礼日時:2010/04/30 00:41

 私は、全く興味がありませんので、読んでみても何の事やらさっぱり理解できないのですが、下記がご参考にならないでしょうか?



●オブジェクト指向の手法によって高度な Web アプリケーションを作成する
http://msdn.microsoft.com/ja-jp/magazine/cc16341 …
>類似のオブジェクトを作成することが必要なときには、“new” を指定してコンストラクタ関数を呼び出すことで、完全に初期化されたオブジェクトを取得できます。
    • good
    • 0
この回答へのお礼

ご回答いただきありがとうございます。
リンク先をじっくり読ませていただきます。
ありがとうございました。

お礼日時:2010/04/30 00:37

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!