prototype.js をできるだけ使わないために
ほぼ備忘録(略して『ほぼ備』)
オブジェクトの継承について考える。
※できるだけ、自然のままの JavaScript 構文を使えるように気をつけました…
ごちゃごちゃくっつけない。
ここ、個人的には重要だと思っております。
<ここから>
まずは Object クラスを汚染しる!(結局 object.js とか作ることに…) :
Object.prototype.extend = function() {
for (var i = 0; i < arguments.length; i++) {
var base = new arguments[i]();
for (property in base) {
if (! this[property]) this[property] = base[property];
}
}
return this;
}
Object.prototype.init = function() {
// 引数がなくても動くように try
try {
this._constructor.apply(this, arguments[0]);
} catch (e) {}
}
うわー、初めから汚染してます、ごちゃごちゃくっつけております。
上記「 extend 」メソッドは prototype.js にも似たようなのが備わってるんですが気にしない(prototype 使う前からやってたし・・・)
あと、p(ry の extend のシンタックス:
Class.extend(Child, Parent); // 「子に」「親を」継承させる
(↑)がイヤだったので
this.extend(Parent); // 「自分が」「親を」継承する
という感じで使えるように。
で、後はもう一つの「 init 」メソッドを使いつつ使用例:
// 親クラス
function Animal() {
Animal.prototype._constructor = function(name) {
this.name = name;
}
Animal.prototype.bark = function() {
alert(this.name);
}
this.init(arguments);
}
// 子クラス
function Dog() {
this.extend(Animal).init(arguments);
}
親クラス、子クラスを定義して実行:
var uma = new Animal('Stitch');
uma.bark(); /* アラート「 Stitch 」 */
var dog = new Dog('Snoopy');
dog.bark(); /* アラート「 Snoopy 」 */
続いて、子クラスでメソッド追加。かつ親クラスのメソッドをオーバーライド:
function Dog() {
Dog.prototype.run = function() {
alert("runs by " + this.speed + ".");
}
// コンストラクタをオーバーライド
Dog.prototype._constructor = function(name, speed) {
this.name = name;
this.speed = speed;
}
this.extend(Animal).init(arguments);
}
実行!:
var dog = new Dog('Snoopy', '30Km/h'); // 引数を追加
dog.bark(); /* アラート「 Snoopy 」*/
dog.run(); /* アラート「 Runs by 30Km/h. 」*/
<ここまで>
function の中に Object.prototype を書くとクラスっぽく見えますね*1。
*1:new の度に定義し直すので無駄は多いけど…