我从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);
介绍正在创建的对象的内部差异?任何内部属性差异,行为差异,以便我应该使用新的方式,并尝试将旧代码转换为新代码?
感谢。
答案 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
属性