プロトタイプチェーンの図とか
自分用に図を描いてみた。JavaScript のプロトタイプチェーン。たぶんきっとこんな感じかなと。

[追記 at 2008/04/30]
constructor プロパティも書き加えた、より汎用的な図はこちらで。
[/追記]
で、これは以下のコードを基に図に起こしたもの。いろんなサイトを巡って勉強するのももちろんだけど、やっぱり自分でコード書かないと身に付かないなぁとしみじみ思ったり。
ちなみに、__proto__ プロパティは基本的には内部プロパティであり、一部のホスト環境でしかアクセスできないのでご注意を。Firefox では動きます。
//画面表示関数
function debugPrint() {
var separator = " ";
alert(Array.prototype.join.apply(arguments, [separator]));
};
/**
* Object <- Worker <- PartTimer <- Cook
* <- Waiter
*/
/**
* 労働者オブジェクト
*/
function Worker() {}
Worker.prototype = {
workedTime: 0,
getMonthlyPay: function() {}
};
/**
* アルバイト オブジェクト
*/
function PartTimer() {}
PartTimer.prototype = new Worker();
PartTimer.prototype.hourlyPay = 800;
PartTimer.prototype.getMonthlyPay = function() {
return this.hourlyPay * this.workedTime;
};
/**
* 調理係オブジェクト
*/
function Cook() {}
Cook.prototype = new PartTimer();
Cook.prototype.advantage = 50;
Cook.prototype.getMonthlyPay = function() {
return (this.hourlyPay + this.advantage)
* this.workedTime;
};
/**
* 接客係オブジェクト
*/
function Waiter() {}
Waiter.prototype = new PartTimer();
//プロトタイプ チェーン
(function() {
var c = new Cook();
//その1
debugPrint("Chain1:",
(c.__proto__ === Cook.prototype),
(c.__proto__.__proto__ === PartTimer.prototype),
(c.__proto__.__proto__.__proto__ === Worker.prototype),
(c.__proto__.__proto__.__proto__.__proto__
=== Object.prototype),
(c.__proto__.__proto__.__proto__.__proto__.__proto__
=== null));
//その2
debugPrint("Chain2:",
(c.__proto__ === Cook.prototype),
(Cook.prototype.__proto__ === PartTimer.prototype),
(PartTimer.prototype.__proto__ === Worker.prototype),
(Worker.prototype.__proto__ === Object.prototype),
(Object.prototype.__proto__ === null));
//その3
debugPrint("Chain3:",
(Waiter.prototype.__proto__ === PartTimer.prototype),
(Cook.prototype.__proto__ === PartTimer.prototype),
(Waiter.prototype.__proto__ === Cook.prototype.__proto__));
})();
//プロパティ探索
(function() {
var c = new Cook();
c.cook = function() { return "Good taste!" };
debugPrint("cook:",
c.hasOwnProperty("cook"));
debugPrint("advantage:",
c.hasOwnProperty("advantage"),
c.__proto__.hasOwnProperty("advantage"));
debugPrint("hourlyPay:",
c.hasOwnProperty("hourlyPay"),
c.__proto__.hasOwnProperty("hourlyPay"),
c.__proto__.__proto__.hasOwnProperty("hourlyPay"));
debugPrint("workedTime:",
c.hasOwnProperty("workedTime"),
c.__proto__.hasOwnProperty("workedTime"),
c.__proto__.__proto__.hasOwnProperty("workedTime"),
c.__proto__.__proto__.__proto__.hasOwnProperty(
"workedTime"));
debugPrint("getMonthlyPay:",
c.hasOwnProperty("getMonthlyPay"),
c.__proto__.hasOwnProperty("getMonthlyPay"));
//[return] true
// c.__proto__.__proto__.hasOwnProperty("getMonthlyPay");
// c.__proto__.__proto__.__proto__.hasOwnProperty(
// "getMonthlyPay");
//[warning] reference to undefined property
// c.hoge;
})();
/**
* 労働者 P オブジェクト
* prototype で workedTime を定義
*/
function WorkerP() {}
WorkerP.prototype = {
workedTime: 0
};
/**
* 労働者 C オブジェクト
* コンストラクタで workedTime を定義
*/
function WorkerC() {
this.workedTime = 0;
}
WorkerC.prototype = {};
/**
* 労働者 W オブジェクト
* prototype で workedTime を定義してコンストラクタから使用
*/
function WorkerW() {
this.workedTime = 0;
}
WorkerW.prototype = {
workedTime: null
};
//オブジェクトのプロパティ探索
(function() {
debugPrint("FunctionObject:",
WorkerP.prototype.hasOwnProperty("workedTime"),
WorkerW.prototype.hasOwnProperty("workedTime"));
//[return] false
// WorkerP.hasOwnProperty("workedTime");
// WorkerP.__proto__.hasOwnProperty("workedTime");
// WorkerC.hasOwnProperty("workedTime");
// WorkerC.prototype.hasOwnProperty("workedTime");
// WorkerC.__proto__.hasOwnProperty("workedTime");
// WorkerW.hasOwnProperty("workedTime");
// WorkerW.__proto__.hasOwnProperty("workedTime");
})();
//インスタンスのプロパティ探索
(function() {
var p = new WorkerP();
var c = new WorkerC();
var w = new WorkerW();
debugPrint("Instanse:",
p.__proto__.hasOwnProperty("workedTime"),
c.hasOwnProperty("workedTime"),
w.hasOwnProperty("workedTime"),
w.__proto__.hasOwnProperty("workedTime"));
//[warning] reference to undefined property
//[Error] has no properties
// p.prototype.hasOwnProperty("workedTime");
// c.prototype.hasOwnProperty("workedTime");
// w.prototype.hasOwnProperty("workedTime");
//[return] false
// p.hasOwnProperty("workedTime");
// c.__proto__.hasOwnProperty("workedTime");
})();
function debugPrint() {
var separator = " ";
alert(Array.prototype.join.apply(arguments, [separator]));
};
/**
* Object <- Worker <- PartTimer <- Cook
* <- Waiter
*/
/**
* 労働者オブジェクト
*/
function Worker() {}
Worker.prototype = {
workedTime: 0,
getMonthlyPay: function() {}
};
/**
* アルバイト オブジェクト
*/
function PartTimer() {}
PartTimer.prototype = new Worker();
PartTimer.prototype.hourlyPay = 800;
PartTimer.prototype.getMonthlyPay = function() {
return this.hourlyPay * this.workedTime;
};
/**
* 調理係オブジェクト
*/
function Cook() {}
Cook.prototype = new PartTimer();
Cook.prototype.advantage = 50;
Cook.prototype.getMonthlyPay = function() {
return (this.hourlyPay + this.advantage)
* this.workedTime;
};
/**
* 接客係オブジェクト
*/
function Waiter() {}
Waiter.prototype = new PartTimer();
//プロトタイプ チェーン
(function() {
var c = new Cook();
//その1
debugPrint("Chain1:",
(c.__proto__ === Cook.prototype),
(c.__proto__.__proto__ === PartTimer.prototype),
(c.__proto__.__proto__.__proto__ === Worker.prototype),
(c.__proto__.__proto__.__proto__.__proto__
=== Object.prototype),
(c.__proto__.__proto__.__proto__.__proto__.__proto__
=== null));
//その2
debugPrint("Chain2:",
(c.__proto__ === Cook.prototype),
(Cook.prototype.__proto__ === PartTimer.prototype),
(PartTimer.prototype.__proto__ === Worker.prototype),
(Worker.prototype.__proto__ === Object.prototype),
(Object.prototype.__proto__ === null));
//その3
debugPrint("Chain3:",
(Waiter.prototype.__proto__ === PartTimer.prototype),
(Cook.prototype.__proto__ === PartTimer.prototype),
(Waiter.prototype.__proto__ === Cook.prototype.__proto__));
})();
//プロパティ探索
(function() {
var c = new Cook();
c.cook = function() { return "Good taste!" };
debugPrint("cook:",
c.hasOwnProperty("cook"));
debugPrint("advantage:",
c.hasOwnProperty("advantage"),
c.__proto__.hasOwnProperty("advantage"));
debugPrint("hourlyPay:",
c.hasOwnProperty("hourlyPay"),
c.__proto__.hasOwnProperty("hourlyPay"),
c.__proto__.__proto__.hasOwnProperty("hourlyPay"));
debugPrint("workedTime:",
c.hasOwnProperty("workedTime"),
c.__proto__.hasOwnProperty("workedTime"),
c.__proto__.__proto__.hasOwnProperty("workedTime"),
c.__proto__.__proto__.__proto__.hasOwnProperty(
"workedTime"));
debugPrint("getMonthlyPay:",
c.hasOwnProperty("getMonthlyPay"),
c.__proto__.hasOwnProperty("getMonthlyPay"));
//[return] true
// c.__proto__.__proto__.hasOwnProperty("getMonthlyPay");
// c.__proto__.__proto__.__proto__.hasOwnProperty(
// "getMonthlyPay");
//[warning] reference to undefined property
// c.hoge;
})();
/**
* 労働者 P オブジェクト
* prototype で workedTime を定義
*/
function WorkerP() {}
WorkerP.prototype = {
workedTime: 0
};
/**
* 労働者 C オブジェクト
* コンストラクタで workedTime を定義
*/
function WorkerC() {
this.workedTime = 0;
}
WorkerC.prototype = {};
/**
* 労働者 W オブジェクト
* prototype で workedTime を定義してコンストラクタから使用
*/
function WorkerW() {
this.workedTime = 0;
}
WorkerW.prototype = {
workedTime: null
};
//オブジェクトのプロパティ探索
(function() {
debugPrint("FunctionObject:",
WorkerP.prototype.hasOwnProperty("workedTime"),
WorkerW.prototype.hasOwnProperty("workedTime"));
//[return] false
// WorkerP.hasOwnProperty("workedTime");
// WorkerP.__proto__.hasOwnProperty("workedTime");
// WorkerC.hasOwnProperty("workedTime");
// WorkerC.prototype.hasOwnProperty("workedTime");
// WorkerC.__proto__.hasOwnProperty("workedTime");
// WorkerW.hasOwnProperty("workedTime");
// WorkerW.__proto__.hasOwnProperty("workedTime");
})();
//インスタンスのプロパティ探索
(function() {
var p = new WorkerP();
var c = new WorkerC();
var w = new WorkerW();
debugPrint("Instanse:",
p.__proto__.hasOwnProperty("workedTime"),
c.hasOwnProperty("workedTime"),
w.hasOwnProperty("workedTime"),
w.__proto__.hasOwnProperty("workedTime"));
//[warning] reference to undefined property
//[Error] has no properties
// p.prototype.hasOwnProperty("workedTime");
// c.prototype.hasOwnProperty("workedTime");
// w.prototype.hasOwnProperty("workedTime");
//[return] false
// p.hasOwnProperty("workedTime");
// c.__proto__.hasOwnProperty("workedTime");
})();
| 固定リンク



コメント