Как объяснил Шон Виейра, первый метод не совпадает со вторым методом. В первом методе экземпляр наследует от Person.prototype
. Во втором методе экземпляр наследует непосредственно от Object.prototype
.
Метод 1:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| Person.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
Метод 2:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
Интересно, что выше диаграммы показывают, что объекты наследуют от других объектов в JavaScript, а не от конструкторов. Следовательно, при создании new Person
экземпляр наследуется от Person.prototype
, а не от Person
.
Как это релевантная информация? Для начала он демонстрирует, что вам не нужно создавать конструктор для создания экземпляров объекта. Вместо этого вы непосредственно создать прототип объекта следующим образом:
var person = {
create: function (name, gender) {
var person = Object.create(this);
person.gender = gender;
person.name = name;
return person;
},
speak: function() {
alert("My name is " + this.name + ".");
}
};
В приведенном выше примере person
эквивалентно Person.prototype
. Теперь вы можете создать экземпляр person
следующим образом:
var bob = person.create("Bob", "M");
Прототип цепи bob
будет выглядеть следующим образом:
null
^
|
| __proto__
|
+------------------+
| Object.prototype |
+------------------+
^
|
| __proto__
|
+------------------+
| person |
+------------------+
^
|
| __proto__
|
+------------------+
| bob |
+------------------+
Так почему вы должны создавать объекты, как это вместо этого?
- Он выглядит чище. Все инкапсулируется в одном объектном литерале.
- Легче понять, что объекты наследуются от объектов. Никаких конструкторов не требуется.
- Чтобы создать экземпляр, вам не нужно использовать
new
. Это solves a lot от problems.
Для получения дополнительной информации об этом шаблоне прочитайте мой пост в блоге на "Why Prototypal Inheritance Matters".
Интересный блог, мне интересно, если вы могли бы объяснить 3 причины, по которым прототипные шаблоны лучше, чем функции конструктора: 1: технически возможно, но вам не нравится синтаксис (проясняется в комментариях). 2.То же, что и 1, не нравится синтаксис и подвержен ошибкам. 3. Не нравится синтаксис, слишком запутанный (такой же, как 1 и 2). То, что мне не хватает, - это техническая основа, которая лучше расширяется или будет работать лучше. В какой-то момент я согласен с тем, что функции конструктора могут быть подвержены ошибкам, но даже до использования компилятора замыкания я почти никогда не злоупотребляю ими (забыв о новых) – HMR
@HMR Я уже ответил на преимущества прототипного наследования по классическому в следующем ответе: http: // stackoverflow .com/а/16872315/783743. Тем не менее я должен признать, что оба эти шаблона эквивалентны по силе, и выбор между одним из них - это только вопрос предпочтения. Однако вы должны заметить, что 'new' намного быстрее, чем' Object.create'. Следовательно, если вы хотите производительность, тогда придерживайтесь 'new'. Я создал небольшую, быструю библиотеку, которая упрощает работу с конструкторами и прототипами (особенно для тех, кто этого не понимает): https://github.com/javascript/augment –
Спасибо за ваш ответ, может быть, это является интересным для вас. Майкл Болин работал над компилятором закрытия и защищает конструкторскую функцию над функциональным шаблоном. Он старый и не упоминает Object.create (прототипный шаблон?). Http://bolinfest.com/javascript/inheritance.php В какой-то момент JavaScript будут иметь классы (Ecma 6) – HMR