2. ちょこっとだけ今までのおさらい
JavaScriptではすべてが実体を持っている。
var f = function() { … };
var v = "val";
最も基本となる Object もその名前で(内部的に)しっかりと存在してい
る。
alert(typeof(Object)); // functionと表示される
関数を実行するには「実行可能なプロパティ」に()をつけてやる。
「実行可能なプロパティ」とはFunctionオブジェクトやfunction式を使って
作成されたものが代入されているもの。
var f = function() { … };
f();
Proprietary and Confidential to Lanchester Co.,LTD. Page 1
6. ひとまずprototypeのことは忘れてthis
function F(str) { // このようなnewで呼ばれることを
this.name = str; // 前提とした関数を俗に「クラス」
} // と呼ぶことがある
var a = new F("Yamama");
// new付きでFが実行され、その中でオブジェクトが作られ、
// そのオブジェクトがthisとなり、そのnameにセットされ、
// そのオブジェクトがaに返されるので・・・
alert(a.name); // a.nameはYamamaとなる
newなしの場合、thisは(関数の中とかじゃない場合)グローバルオブジ
ェクト(ここではwindow)を指しているので
F("Hoge"); // this.name→window.nameとなり
alert(name); // 意図しない変数としてセットされてしまう
Proprietary and Confidential to Lanchester Co.,LTD. Page 5
7. ひとまずprototypeのことは忘れてthis、その2
function F(str) {
this.name = str;
this.show = function() { alert(this.name); }
}
var a = new F("Yamama");
a.show();
// aはプロパティとして関数を持っているので実行可能
// この、あるインスタンスが持っている「関数プロパティ」を
// 俗に「メソッド」と呼ぶことがある
F("Hoge");
show(); // this.show→window.showなので実行できちゃう
// こうならない作り方もあるけど難しいので割愛
Proprietary and Confidential to Lanchester Co.,LTD. Page 6
8. prototypeを忘れていた弊害、それは
var a = new F("Yamama");
a
var b = new F("Edogawa");
name: "Yamama"
:
show: function() { … }
と、いっぱいインスタンス化すると、
var a = { b
name: "Yamama", name: "Edogawa"
show: function(){ alert(this.name); } show: function() { … }
};
のように作られていることと同じになり、すべてのインスタンス(aやbな
ど)がすべて「show」というメソッドを持っていることになる。
この調子でインスタンスを増やしていくとメモリ的にちょっと勿体無い。
alert(a.hasOwnProperty("show")); // aがshowというプロパティを
// 持っているか?
// true ←当然よね
Proprietary and Confidential to Lanchester Co.,LTD. Page 7
9. そしてprototypeの出番
function F(str) {
this.name = str;
F.prototype.show = function() { // 関数名.prototype
alert(this.name); // は丸暗記でおk
}
}
var a = new F("Yamama");
a.show();
alert(a.hasOwnProperty("show"); // false
なんで持ってないプロパティを参照(実行)できるのか?
Proprietary and Confidential to Lanchester Co.,LTD. Page 8
12. とあるインスタンスだけ動作を変える
function F(str) {
this.name = str;
F.prototype.show = function() { alert(this.name); }
}
var a = new F("Yamama");
var b = new F("Edogawa");
a.show = function() { alert("I am " + this.name); }
a.show(); // I am Yamama
b.show(); // Edogawa
delete a.show; // aが(直接)持ってるshowを削除
a.show(); // Yamama(元のようにprototypeチェインを辿る)
Proprietary and Confidential to Lanchester Co.,LTD. Page 11
13. 内部的には・・・
F
prototype.show: function() { … }
a b
show: function() { … }
a.show()が呼ばれる b.show()が呼ばれる
自分の持っているshowメソッド bはshowメソッドを持っていな
を実行 い
[[prototype]]を辿りメソッド
を実行
Proprietary and Confidential to Lanchester Co.,LTD. Page 12