Возможно, я читал 15 разных книг, статей или вопросов, связанных с прототипом JavaScript, и каждый из них имел несколько разные способы делать вещи, поэтому я хотел разобраться в этом раз и навсегда:Настройка наследования прототипа
Пример
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()
, получит свойства высоты и ширины на своем прототипе, что может привести к проблемам, правильно?
Может кто-то пролить свет на это? Благодаря!
EDIT
Я также понял, что при использовании new Rectangle()
в качестве прототипа площади, он на самом деле вызывает конструктор (который может сделать что-то полезное в некоторых случаях), в то время как метод Object.create()
не делает. Является ли обоснование двух разных способов использования, связанных с вариантом использования, в том, следует ли вызывать конструктор для создания некоторого состояния объекта, которое может понадобиться в подтипе?
Раз и навсегда? Используйте синтаксис ES6 'class'. – Bergi
Да, но не все браузеры могут использовать ES6 еще, и я не использую Babel в данный момент. Плюс его больше о понимании, что происходит под капотом, который меня интересует. –