目前,我在JavaScript库中实现了继承,如下所示:
parent = function() { };
parent.prototype.hello = function() { alert('parent'); };
child = function() { };
child.prototype = parent.prototype;
但是,我注意到当我覆盖子类“class”原型中的函数时,它也会不合理地覆盖父类的原型:
child.prototype.hello = function() { alert('child'); }
(new parent()).hello(); // alerts "child" --> undesirable
(new child()).hello(); // alerts "child" --> desirable
如果我从孩子的原型中删除了一些东西
delete child.prototype.hello;
然后父母的原型受到不利影响。所以,也许
child.prototype = parent.prototype;
不是实现继承的最佳方式吗?而不是让孩子“类”引用父原型,或许将复制父原型更有意义吗?
_.extend(child.prototype, parent.prototype);
答案 0 :(得分:9)
child.prototype = parent.prototype;
不正确,因为您已在问题中详细说明。
使用_.extend
也不是您想要的。考虑一下"继承的变化"父原型属性将不导致孩子的变化:
// perform extension
_.extend(child.prototype, parent.prototype);
// parent later gains new property after extension
parent.prototype.parentProp = function() { alert("new"); };
(new parent()).parentProp(); // alerts "new" --> desirable
(new child()).parentProp(); // error; doesn't exist --> undesirable
你可能想要child.prototype = Object.create(parent.prototype);
这说:"在child.prototype
中存储一个新对象。这个新对象使用parent.prototype
对象作为自己的原型。"这会导致真正的继承发生,因为当child
实例想要一个属性时,它首先查找它自己的属性,然后查看它的直接原型(child.prototype
),然后查看它的原型。原型(parent.prototype
)。
原型链
使用child.prototype = parent.prototype
时,实例的原型链如下所示:
{ child instance } ==> { only prototype }
{ parent instance } ==> { only prototype }
其中only prototype
是child.prototype
和parent.prototype
引用的共享对象。
使用_.extend(child.prototype, parent.prototype)
时,子原型和父原型是不同的,但没有直接继承。更改父原型根本不会改变孩子,因为我们只是在一个时间点将父原型的属性复制到子原型中。
{ child instance } ==> { child.prototype }
{ parent instance } ==> { parent.prototype }
使用child.prototype = Object.create(parent.prototype);
实际上,从父级原型到子原型发生继承:
{ child instance } ==> { child.prototype } ==> { parent.prototype }
{ parent instance } ==> { parent.prototype }