2007年08月06日

new演算子の件

JavaScriptのオブジェクトを作成する件で混乱していました。
オブジェクトを作成するのに、
var Hoe = {name:'hoe desu', type:'object literal desu!'}
としても、
var Hoehoe = function() {
this.name = 'hoehoe desu!';
this.type = 'function desu!';
}
としても良いとあるのに、「何かが違う」のです。
何が違うのかわからないのですが、作成したオブジェクトに対して何かしようとすると片方はできるのにもう片方はできなかったり…。

そのひとつが new する事でした。
var hoe = new Hoe(); //エラー。Hoe is not a constructor
で、
var hoehoe = new Hoehoe();
はもちろんエラーにはならないのです。
「new演算子はコンストラクタ関数のあるオブジェクトのインスタンスを作成する」ものだからです。
じゃあ、コンストラクタ関数って何?となりますが、これは、ちょっと置いておいて。


もうひとつがprototypeプロパティです。
alert(Hoe.prototype); //undefined
hoe.prototype.hoe_proto = 'hoe_proto degansu!'; //エラー。hoe.prototype ha no property
で、
alert(Hoehoe.prototype); //[object Object]
Hoehoe.prototype = 'hoehoe_proto degansu!';
はもちろんエラーにはならないのです。
さらにはもちろん
var hoehoe = new Hoehoe();
alert(hoehoe.hoehoe_proto); //'hoehoe_proto degansu!'
なのです。


さて、newの件に戻ります。
objectName = new objectType(param1 [,param2] ...[,paramN])
となっています。
objectType??と思うわけです。で、
 objectType 
Object type. It must be a function that defines an object type.
となっているわけです。
object typeを作成するには、
1. 関数を記述してobject typeを定義する
2. newでインスタンスを作る
とあります。
object typeを定義するには、object typeの為に名前、プロパティ、メソッドを指定する関数を作成します。
という事です。どうやらオブジェクトとobject typeというのは別物らしいと、ここら辺で気がつきました。
じゃあ、object typeとコンストラクタの関係は?
「1. 関数を記述してobject typeを定義する」の関数がコンストラクタ関数です。要するにobject typeというのは、コンストラクタそのものという事ですね。
関数 = object type = コンストラクタ

です。関数がthisを使ってプロパティを設定していなくても、それはコンストラクタなのです。なんだか元に戻った感じがします。

次。prototypeの件。
まず、prototypeは全てのオブジェクトの親である、グローバルオブジェクトObjectのプロパティではありますが、これはFunctionオブジェクトのプロパティprototypeなのです。つまりobject typeのプロパティ、コンストラクタのプロパティです。
prototypeの役目は、shared propety、共有プロパティなので、共有できないただのオブジェクトにあってもしょうがない?newして共有できる関数オブジェクトにだけあるという見方はできるのでしょうか。


var hoe1 = {
name:'hoe desu!',
age:40
}
で作成されたオブジェクトhoe1は、
var Hoe = function(){
this.name = 'hoe desu!';
this.age = 40;
}
var hoe2 = new Hoe();
で作成されたオブジェクトhoe2にあたるものと思えば良い訳ですね?
このエントリで書いた混乱の元は、なんとなくプロトタイプベースの言語というののイメージが頭で出来上がっていて、それは「オブジェクトからオブジェクトを作成する」というもので、「何かオブジェクトがあれば、それを直接newしてオブジェクトを作成できるんだ」と思い込んでいた事が原因のようです。
クラスベースの言語と同じように、オブジェクトの型(object type)というものがあって、そこから新しくオブジェクトを作るのですね。
何でもnewすりゃいいじゃん!htmlでテーブルが定義されていたら、それをnewしてもう一個テーブルが作れるじゃん!とかテーブルの列をnewして同じ列が作れるじゃん!勘違いしている事もありました。

hoe = function(p) {
this.val = p;
}
hoe.prototype.setVal = function(p) {
this.val = p;
}
hoe.prototype.getVal = function() {
return this.val;
}
としている時に、このhoeのprototypeプロパティはなんだろうと思ったらよくわからなくなってしまいました。
関数?でも
prototype = function() {...}
じゃないしなぁ。とか
オブジェクト?でもsetValとgetValと2つも定義してるんだけど…。とか。
で、"名前"と"値"の組は全てオブジェクトなのです。
hoe.prototype = {
getVal = function() {...},
setVal = function() {...}
}
と書き換えると、オブジェクトなんだっていう見方がしやすいかと思います。
obj = {}
が一番簡単なオブジェクトですもんね。
posted by ほえ at 16:03| Comment(0) | TrackBack(0) | JavaScript | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.seesaa.jp/tb/50479429
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。