私は JavaScript のスキルを更新していて、オブジェクトが別のオブジェクトから継承できる方法を考え出しました。継承はツリー状にする必要があります。
Parent->Child->Child2
を拡張しましたFunction.prototype
(これは悪い考えだと言わないでください。これは後で変更できます)
Function.prototype.extend = function(child)
{
// save child prototype
var childPrototype = child.prototype;
// copy parent to child prototype
child.prototype = Object.create(this.prototype);
// merge child prototype
for (var property in childPrototype) {
child.prototype[property] = childPrototype[property];
}
child.prototype.constructor = child;
child.prototype.$parent = this.prototype;
return child;
};
親オブジェクト:
var Parent = (function()
{
var Parent = function(x, y)
{
this.x = x;
this.y = y;
console.log('Parent constr', x, y);
}
Parent.prototype.move = function(x, y)
{
this.x += x;
this.y += y;
console.log('Parent moved.');
};
return Parent;
}());
第一子:
var Child = Parent.extend(function()
{
var Child = function(x, y)
{
this.$parent.constructor(x, y);
console.log('Child constr');
}
Child.prototype.print = function()
{
console.log('Child print', this.x, this.y);
};
// override
Child.prototype.move = function(x, y)
{
this.$parent.move(x, y);
console.log('Child moved.');
};
return Child;
}());
2 番目の子:
var Child2 = Child.extend(function()
{
var Child2 = function(x, y)
{
this.$parent.constructor(x, y);
console.log('Child2 constr');
}
// override
Child2.prototype.move = function(x, y)
{
this.$parent.move(x, y); // call parent move
console.log('Child2 moved.');
};
return Child2;
}());
ここまでは順調ですね。親のコンストラクターとメソッドを呼び出し、メソッドをオーバーライドすることさえできます。
var child = new Child2(1, 1);
child.move(1, 1);
child.print();
次の正しい出力が得られます。
Parent constr 1 1
Child constr
Child2 constr
Parent moved.
Child moved.
Child2 moved.
Child print 2 2
しかし、2 番目の子からオーバーライドをコメントアウトすると、次の出力が得られます。
Parent constr 1 1
Child constr
Child2 constr
Parent moved.
Child moved.
Child moved. -> WHY??
Child print 2 2
Child moved.
2回出力される理由がわかりません。結果は正しいですが、何か奇妙なことが起こっています。
編集:
最後に、問題を調査してさらに掘り下げた後、私は素晴らしい解決策を見つけました:
// call method from parent object
Object.getPrototypeOf(Child2.prototype).move.apply(this, arguments);
に別の拡張機能を作成しましたFunction
:
Function.prototype.getParent = function()
{
return Object.getPrototypeOf(this.prototype);
};
次に、たとえばChild2
move メソッド:
Child2.prototype.move = function(x, y)
{
Child2.getParent().move.call(this, x, y);
};
だから私はもう必要が$parent
なく、望ましい結果が得られます。
別の解決策は、親プロトタイプを直接呼び出すことです。
Child2.prototype.move = function(x, y)
{
Child.prototype.move.call(this, x, y);
};