我可能读过 15 本不同的书籍、文章或与 JavaScript 原型(prototype)继承相关的问题,每本的做事方式都略有不同,所以我想一劳永逸地弄清楚这一点:
示例
function Rectangle(h, w){
this.height = h;
this.width = w;
console.log("Rectangle ctor: "+ this.height + "x" + this.width);
}
Rectangle.prototype.getArea = function(){
return this.height * this.width;
}
var a = new Rectangle(3, 4);
console.log(a.getArea());
function Square(l){
this.height = l;
this.width = l;
console.log("Square ctor");
}
Square.prototype = new Rectangle();
Square.prototype.constructor = Square;
var b = new Square(5);
console.log(b.getArea());
此示例按预期工作。 Square 对象继承自 Rectangle,因此,它能够使用 getArea()
方法。然而,有一件事我总是看到根据我的观察位置不同,做的方式也不同。
而不是做Square.prototype = new Rectangle()
,我见过有人用Square.prototype = Object.create(Rectangle.prototype)
。当我对此进行测试时,两者似乎都以相同的方式运行,我注意到的唯一区别是当我这样做时:
console.log(new Rectangle());
console.log(Object.create(Rectangle.prototype));
这会记录 new Rectangle()
其中包括height
和width
属性,然后记录 Object.create(Rectangle.prototype)
除了 height
之外,它记录相同的内容和width
.
所以我的问题是,为什么有些人会用其中一种而不是另一种呢?一种比另一种更有利吗?按照我的理解,使用 new Rectangle()
的那个将获取其原型(prototype)上的高度和宽度属性,这可能会导致问题,对吗?
有人可以解释一下吗?谢谢!
编辑
我还意识到,当使用new Rectangle()
时作为 Square 的原型(prototype),它实际上调用了构造函数(在某些情况下可能会做一些有用的事情),而 Object.create()
方法没有。两种不同用法背后的推理是否与用例相关,即是否应该调用构造函数来生成子类型中可能需要的某些对象状态?
最佳答案
我想你自己已经回答了你的问题。 new Rectangle()
和 Object.create(Rectangle.prototype)
之间的区别在于前者调用构造函数而后者不调用构造函数。因此,您应该始终使用Object.create()
。否则,构造函数将被调用两次(如您在示例中所见)。
此外,在 ECMAScript 6 中您可以使用 class
syntax ,这简化了很多事情,比如继承。
关于javascript - 原型(prototype)继承设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39496129/