我精通 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
也会更改原型Obj3
和函数Obj1
本身。这对这位 C++ 程序员来说是非常令人震惊的,尽管这正是我从上述语法中所期望的:毕竟,由于 和 的原型Obj2
都Obj3
等同于Obj1
,因此对一个的更改将产生对另外两个相同的更改。不过,我想将andObj1
用作两者的基类,Obj2
并在其上插入一个新函数,它不会以任何方式由or共享。我怎么做?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()