对于使用JavaScript的继承,引用或复制父级原型是否更好?

时间:2014-11-17 17:16:11

标签: javascript inheritance prototype

目前,我在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);

1 个答案:

答案 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 prototypechild.prototypeparent.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 }