javascript继承中正确的原型做法是什么?

时间:2013-12-13 15:48:30

标签: javascript inheritance

我已经阅读了几篇关于js继承的文章(this onethis onethis one等。)

在Mozilla的this article中,“经典”继承如下所示:(我统一化的例子)

// inherit Base
function Derived() { ... }
Derived.prototype = new Base();            <-------
Derived.prototype.constructor = Derived;   <-------

但是在this article我看到了:

// inherit Base
function Derived() { ... }
Derived.prototype = Object.create(Base.prototype);    <-------
Derived.prototype.constructor = Derived;

此外我也看到了这个:

Derived.prototype = Base.prototype;

我也进行了实验,但未能找到constructor做作的用法:

Derived.prototype.constructor = Derived; <--- it still work if I skip this line

如果我跳过此行,new Derived()无论如何都会正确调用Derived()

所以1)什么是正确的:

  1. Derived.prototype = new Base();
  2. Derived.prototype = Object.create(Base.prototype);
  3. Derived.prototype = Base.prototype;
  4. 其他?
  5. 而且2)真的需要Derived.prototype.constructor = Derived;吗?为什么?

2 个答案:

答案 0 :(得分:3)

Derived.prototype = new Base();

这只是为了设置原型链而调用Base构造函数。虽然有时候工作并给予Object.create相同的结果,但它容易出错,应该避免。阅读What is the reason to use the 'new' keyword at Derived.prototype = new Base(以及的原因)。

Derived.prototype = Object.create(Base.prototype);

这是最先进的 - Correct javascript inheritance可以说。

Derived.prototype = Base.prototype;

This is plain wrongDo not use。它允许BaseDerived实例从相同的对象继承 - 而它(很少)可以帮助为“类”提供多个构造函数,这不是“子类化” ”

  

真的需要Derived.prototype.constructor = Derived;吗?为什么呢?

它可以省略,但你的脚本仍然可以工作,但为方便起见,你会期望(new Derived).constructor === Derived。另请查看JavaScript inheritance and the constructor property

答案 1 :(得分:1)

在JavaScript中进行经典继承的正确方法是什么

this回答中,我解释了1和2之间的区别,说明为什么2是在JavaScript中模拟经典继承的最佳方式。

简而言之,在解决方案1中,子级继承自父级的实例。在解决方案2中,子类(Derived.prototype)继承自父类(Base.prototype)的类。这对父类施加了严格的限制,因为必须使用0参数调用它。

第三种解决方案更糟糕,因为Derived和Base类的原型是同一个对象,因此不能进行任何方法覆盖。更糟糕的是,Derived.prototype中定义的方法将可用于所有Base实例,如果在Base.prototype上声明了具有相同名称的方法,则只需替换它。

结论:2是在JavaScript中进行经典继承的真正方法。

设置所需的构造函数属性

在原型上设置constructor属性使其可供所有实例访问。这只是为了方便,继承部分在没有它的情况下工作。