私は C++ に堪能なので、OOP のバックグラウンドは十分にありますが、JavaScript は初めてで、JavaScript でポリモーフィズムを適切に実装する方法を理解しようとしています。このトピックに関連する多くのチュートリアルと StackOverflow の質問を読みましたが、基本クラスから正しく継承し、新しいメンバーを子クラスに追加する方法について詳細に説明したものはありません。
function Obj1() {}
function Obj2() {}
function Obj3() {}
Obj2.prototype === Obj3.prototype; // false
好奇心 #1:Obj2
とObj3
(さらに言え ば ) の両方が をObj1
継承しObject
ている場合、それらのプロトタイプが同一でないのはなぜですか? Obj2
とObj3
それぞれが の独自のコピーを受け取りましたかObject
?
Obj2.prototype = Object;
Obj2.prototype = Object;
Obj2.prototype === Obj3.prototype; // true
Obj2.prototype = Obj1;
Obj3.prototype = Obj1;
Obj2.prototype === Obj3.prototype; // true
好奇心 2: どちらの場合も、Obj2
現在Obj3
は同じプロトタイプを共有しています。変化したこと?
Obj2.prototype.pi = function() { return 3.14159; }
Obj2.prototype.pi(); // 3.14159
Obj3.prototype.pi(); // 3.14159
Obj1.pi(); // 3.14159
本当の問題: のプロトタイプを変更すると、 のプロトタイプと関数自体Obj2
も変更されます。この C++ プログラマーにとって、これはすべて非常にショッキングなことですが、上記の構文からまさに私が予想したとおりでした。結局のところ、 と のプロトタイプは両方とも と同一視されているため、1 つを変更すると、他の 2 つも同じように変更されます。それにもかかわらず、との両方の基本クラスとして使用し、またはによってまったく共有されない新しい関数を挿入したいと考えています。それ、どうやったら出来るの?Obj3
Obj1
Obj2
Obj3
Obj1
Obj1
Obj2
Obj3
Obj2
Obj1
Obj3
これらのオブジェクトがインスタンス化されると、さらに興味深いことが起こります。
var x = new Obj2();
x.pi(); // 3.14159
var y = new Obj3();
y.pi(); // 3.14159
var z = new Obj1();
z.pi(); // Error: pi() not defined on z.
Obj2
Obj3
両方とも関数を持っています。これは、関数を含む基本クラスpi()
を共有していることを意味します。この基本クラスは他ではありません— しかし、反対の証拠にもかかわらず、のインスタンスには が含まれていません!pi()
Obj1
Obj1
pi()