Sub.prototype = new Base()vs Sub.prototype = Base.prototype

时间:2014-10-25 18:55:39

标签: javascript inheritance prototype-programming

在线有很多关于JavaScript原型设计和继承的资源。其中大多数使用与此类似的代码:

function Base() {}
function Sub() {}

继承实现如下:

Sub.prototype = new Base();

但我想知道以这种方式实现的继承有什么问题:

Sub.prototype = Base.prototype;

似乎第二个也同样有效。我发现的唯一两个差异(IMO是第二种方法的优势)是:

  • 显然有一个Base虚拟实例化 更好,因为实例从未使用过
  • 检查实例 表明第一种方法产生两个嵌套__proto__ 属性,而第二个唯一的,这使得 实例清洁工。

后者在下面的代码片段中说明:

function Base(){}
Base.prototype.bogus = function(){};
function SubNew(){}
function SubProto(){}

SubNew.prototype = new Base();
SubProto.prototype = Base.prototype;

var sn = new SubNew();
var sp = new SubProto();

console.log(sn);
console.log(sp);

给出:

code snippet output

但我的印象是我在这里错过了一些非常重要的观点。我的问题是:针对第二种方法的情况是什么?

5 个答案:

答案 0 :(得分:4)

当您向Sub.prototype添加新属性时,您不希望它影响Base.prototype,是吗?那会很破碎。 : - )

使用new Base()方法意味着您对Sub.prototype所做的任何更改都会通过"泄漏。到Base.prototype

答案 1 :(得分:4)

我会像这样设置

function Base() {}

function Sub() {
  // call parent constructor; optional
  Base.call(this);
}

Sub.prototype = Object.create(Base.prototype, {constructor: {value: Sub}});

这与util.inherits在node.js

中的工作方式非常相似

答案 2 :(得分:3)

如果您使用Sub.prototype = Base.prototype;,则无法将任何方法添加到Sub.prototype,而不会将它们显示在Base.prototype中,因为它们是同一个对象。
除了构造函数之外,Sub和Base将是完全相同的类。

答案 3 :(得分:2)

当你使用相同的原型时,你不会继承任何东西,你只是制作另一种类型的副本。

如果你在基类型对象中放入任何东西,如果你只是获得原型,它将不会被继承:



function Base(){
  this.answer = 42;
}

function SubNew(){}
function SubProto(){}

SubNew.prototype = new Base();
SubProto.prototype = Base.prototype;

var sn = new SubNew();
var sp = new SubProto();

// show result in StackOverflow snippet
document.writeln(sn.answer);
document.writeln(sp.answer);




答案 4 :(得分:0)

基本上,如果您分配prototype属性,那么您将创建另一个构造函数,该构造函数将创建对同一对象进行原型化的对象,而不是继承,您将通过此示例清楚地看到它:

function Base() { }
function SubType() { }
function YourCase() { }

SubType.prototype = Object.create(Base.prototype);
YourCase.prototype = Base.prototype;

Base.prototype.foo = 1;
SubType.prototype.foo = 2;
YourCase.prototype.foo = 3;

console.log(new Base().foo); // 3 WAT?
console.log(new SubType().foo); // 2
console.log(new YourCase().foo); // 3

Fiddle example

如果我们在编辑YourCase.prototype = Base.prototype时在子类型YourCase.prototype上使用相同的对象,那么您也在编辑Base.prototype,因为它们是同一个对象。

这就是为什么你必须使用Object.create(Base.prototype)new Base()来扩展原型。