Любой, кто занимается фронтенд-разработкой или играет с JavaScript, знает, что объект-прототип и цепочка прототипов — одна из самых важных точек знаний в JavaScript, а также вопросы, которые необходимо задавать на собеседованиях по фронтенду. Крайне важно хорошо освоить прототип и цепочку прототипов. Поэтому я буду использовать две статьи (или даже больше), чтобы объяснить объект-прототип и цепочку прототипов соответственно.
В предыдущей статье мы подробно представили процесс выполнения и возвращаемое значение конструктора, если вы не читали, перейдите по ссылкеJS Advanced (1): Конструктор, понятный каждомуЧитайте дальше, потому что это основы этой статьи.
Без лишних слов, давайте к делу.
1. Зачем использовать объекты-прототипы
Из введения предыдущей статьи мы знаем, что:
function Person(name, age) {
this.name = name;
this.age = age;
}
var p1 = new Person('Tom', 18);
var p2 = new Person('Jack', 34);
console.log(p1.name, p1.age); // 'Tom', 18
console.log(p2.name, p2.age); // 'Jack', 34
Однако в объекте могут быть не только свойства, но и методы:
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function() {
console.log('Hello');
};
}
var p1 = new Person('Tom', 18);
p1.say(); // 'Hello'
var p2 = new Person('Jack', 34);
p2.say(); // 'Hello'
Мы обнаружили, что экземплярыp1и экземплярp2Вызывается тот же метод, оба распечатываютHelloрезультат. Однако совпадают ли их адреса памяти? Распечатаем:
console.log(p1.say == p2.say); // false
Результат, конечноfalse. Поскольку мы говорили в предыдущей статье, каждый раз, когда он вызывается в виде конструктора, будет открываться новое пространство памяти, поэтому экземплярp1а такжеp2Адреса памяти, на которые указывают, различны. Но в это время будет неловкая проблема,p1а такжеp2называетсяsayМетод и функция те же.Если в классе 60 учеников, нам нужно вызвать один и тот же метод 60 раз, но нам нужно открыть 60 разных областей памяти, что приведет к ненужным тратам. На данный момент объект-прототип может помочь нам решить эту проблему.
2. Как использовать объекты-прототипы
когда функция(примечание: не только конструкторы)После его создания будетprototypeсвойство, значением этого свойства является объект, мы называем этот объект, называемыйпрототип объекта. В то же время, пока к объекту-прототипу добавляются свойства и методы, к этим свойствам и методам могут обращаться экземпляры функции.
Поскольку экземпляр функции может получить доступ к свойствам и методам объекта-прототипа, мы могли бы также изменить приведенный выше код.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function() {
console.log('Hello');
};
var p1 = new Person('Tom', 18);
var p2 = new Person('Jack', 34);
console.log(p1.say === p2.say); // true
В этот момент мы видим экземплярp1и экземплярp2изsayуказывают на одно и то же пространство памяти. Что является причиной этого? Давайте посмотрим на результаты печати консоли.
На скриншоте выше мы видим, чтоPerson.prototypeа такжеp1.__proto__,p2.__proto__похоже, то же самое. Чтобы проверить нашу гипотезу, мы пытаемся напечатать:
Person.prototype === p1.__proto__; // true
Person.prototype === p2.__proto__; // true
p1.__proto__ === p2.__proto___; // true
Мы обнаружили, что все результатыtrue. И это точно объясняет, почемуp1.say === p2.sayправда .
В-третьих, нарисуйте диаграмму отношений конструктор-прототип объект-экземпляр.
Теперь у вас есть общее представление об объектах-прототипах и преимуществах их использования. Далее мы глубоко поймем описанный выше процесс, нарисовав графику.
В качестве примера возьмем следующий код:
function Person(name) {
this.name = name;
}
Person.prototype.say = function() {
console.log('I am saying');
}
var p1 = new Person('Tom');
1. После того, как функция Person будет создана, она сгенерирует пространство памяти, и естьprototypeАтрибуты
2. prototypeЗначением свойства является объект, который мы называем объектом-прототипом.
3. Свойства и методы в объекте-прототипе
Ссылаясь на скриншот консоли выше, мы можем знать, что:
(1) На объекте-прототипе есть
constructorсвойство указывает на Person; (2) На объекте-прототипе естьsayметод, откроет новое пространство памяти; (3) На объекте-прототипе имеется__proto__Атрибуты, о которых мы расскажем в следующей статье.
Согласно нашему анализу выше, продолжайте рисовать:
4. Свойства и методы в экземплярах
когдаp1После создания этого экземпляра будет открыто новое пространство памяти. На данный момент, все еще ссылаясь на скриншот консоли выше, мы можем знать, что:
(1)
p1один из экземпляровnameАтрибуты; (2)p1один из экземпляров__proto__свойство, указывающее на конструкторPersonобъект-прототип.
Согласно вышеприведенному анализу продолжаем рисовать:
4. Резюме
Благодаря приведенному выше объяснению вы сможете понять, что такое объект-прототип и зачем использовать объект-прототип. Наконец, давайте подытожим основные моменты этой статьи.
-
После создания функции будет
prototypeсвойство, значение этого свойства является объектом, мы называем этоprototypeПространство памяти, на которое указывает свойство, называется объектом-прототипом этой функции. -
Объект-прототип функции будет иметь
constructorсвойство, которое указывает на саму функцию.
function Person() {
// ...
}
console.log(Person.prototype.constructor === Person); // true
- Когда функция вызывается как конструктор, создается экземпляр конструктора. Этот экземпляр будет иметь
__proto__Свойство, это свойство указывает на объект-прототип конструктора экземпляра (также известный как объект-прототип экземпляра).
function Person() {
// ...
}
var p1 = new Person();
console.log(p1.__proto__ === Person.prototype); // true
Наконец, в этой статье описывается только диаграмма отношений конструктор-прототип, объект-экземпляр, а не полная цепочка прототипов. Сначала вы можете понять эту часть, а когда я объясню цепочку прототипов, я нарисую полную диаграмму цепочки прототипов, чтобы все могли ее понять. Детская обувь может сначала попытаться понять сегодняшнюю статью и нарисовать диаграмму отношений конструктор-прототип объект-экземпляр, я считаю, что ваши успехи будут больше.
И последнее, но не менее важное: то, что я сказал, не обязательно верно, вы должны попробовать сами!
(Конец этой статьи)