有两种方法可以改变javascript对象的原型,它们之间的区别是什么?

时间:2016-08-17 03:09:53

标签: javascript object inheritance prototype

我从stackoverflow读取了这段代码,它表明了如何实现"继承"在javascript中

var Base=function(){this.a='abc'};
var Sub = function () {};
Sub.prototype = new Base(); // note: this pattern is deprecated!
//Because we used 'new', the [[prototype]] property of Sub.prototype
//is now set to the object value of Base.prototype.
//The modern way to do this is with Object.create(), which was added in ECMAScript 5:
Sub.prototype = Object.create(Base.prototype);

我想知道,如果

  

Sub.prototype = new Base();

不推荐使用

,采用新的方式

  

的Object.create(Base.prototype);

介绍正在创建的对象的内部差异?任何内部属性差异,行为差异,以便我应该使用新的方式,并尝试将旧代码转换为新代码?

感谢。

2 个答案:

答案 0 :(得分:1)

Imho现代的做相关事情的方式是class和相关的关键字。

您建议的两个选项会产生不同的结果。见classical inheritance with Object.create。您缺少对超级构造函数的调用以及将prototype.constructor重新分配给正确的值(在其他情况下也会丢失)。

如链接中所述,使用Object.create进行继承时,与分配new Base()相比,可以找到属性的一个区别:



function Base() { this.baseProp = "baseProp"; }
function Sub() { this.subProp = "subProp"; }

Sub.prototype = new Base();
Sub.prototype.constructor = Sub;

let obj = new Sub();
console.log("obj.baseProp: " + obj.baseProp);
console.log("Has baseProp on itself: " + obj.hasOwnProperty("baseProp"));






function Base() { this.baseProp = "baseProp"; }
function Sub() {
  Base.call(this);
  this.subProp = "subProp";
}

//Note that here Base.prototype doesnt even have anything interesting
Sub.prototype = Object.create(Base.prototype);
Sub.prototype.constructor = Sub;

let obj = new Sub();
console.log("obj.baseProp: " + obj.baseProp);
console.log("Has baseProp on itself: " + obj.hasOwnProperty("baseProp"));




另请注意,Object.create仍会将额外的间接推送到原型链中(其他方法包含Base属性的对象)。但是,额外的步骤不是"错误"但可以看作是Sub的原型属性的拆分和继承的原型属性(例如,如果你想向Sub.prototype添加一些东西,你就很难在没有这种间接的情况下这样做,就像你会不小心添加到Base.prototype以及



function Base() { this.baseProp = "baseProp"; }
Base.prototype.someFunction = () => void 0;
function Sub() {
  Base.call(this);
  this.subProp = "subProp";
}

//Now this is important, the prototype contains something
Sub.prototype = Object.create(Base.prototype);
Sub.prototype.constructor = Sub;

let obj = new Sub();
console.log("First level link has function: " + obj.__proto__.hasOwnProperty("someFunction"));
console.log("Second level link has function: " + obj.__proto__.__proto__.hasOwnProperty("someFunction"));




答案 1 :(得分:0)

我可以指出的唯一区别是,当您使用new时,Sub的原型是Base实例。这意味着所有属性将在子类上可用(不仅仅是原型方法)。

因此,在您的示例中,Sub.prototype = Object.create(Base.prototype);不会继承任何内容。虽然Sub.prototype = new Base()继承了a属性