Прежде чем перейти к тому, что такое прототип, давайте сначала рассмотрим некоторые из основных концепций.

Тип данных для любого языка программирования - это тип данных, которые язык может интерпретировать и изменять в процессе выполнения.

В JavaScript очень фундаментальный тип данных - это объект. Объект - это не что иное, как неупорядоченный набор свойств. У каждого свойства есть имя и значение, связанное с ним. Доступ к этим свойствам можно получить через переменную, содержащую ссылку на объект, для которого это свойство определено. Когда вы привыкли программировать на JavaScript, вы почти всегда будете иметь дело с объектами.

В этой статье я не буду объяснять, как используются объекты и когда вы должны их использовать, но эта статья направлена ​​на то, чтобы дать четкое представление о прототипах в JavaScript. Я пишу эту статью, потому что эта тема может сначала вам нервировать, когда вы ее изучаете, но она станет очень простой, если вы четко ее поймете, и в этой статье я поделюсь своими двумя центами и своей точкой зрения на прототипы, хотя в Интернете есть много хороших статей.

Прототип

В JavaScript с каждым объектом связан другой объект JavaScript. Связанный объект известен как прототип. Итак, с каждым объектом в JavaScript связан объект-прототип. Каждый объект наследует свойства от объекта-прототипа, и именно так достигается наследование в JavaScript. Вы можете спросить: «Хорошо, теперь мы знаем, что с каждым объектом связан объект-прототип, и он ведет себя как его родительский объект, но как мы узнаем, что это за родительский объект?»

Доступ к объекту-прототипу

Помните, я сказал, что каждый объект JavaScript представляет собой неупорядоченный набор свойств? Каждый объект имеет свойство с именем __proto__ , значение которого является прототипом или родительским объектом для текущего объекта, к которому осуществляется доступ к этому свойству. Изменяя значение свойства __proto__, можно изменить объект-прототип любого объекта и создать свою собственную иерархию! Звучит довольно круто, не так ли?

Но речь идет только о доступе к объекту-прототипу или его изменении, но как мы ответим на такие хитрые вопросы, как заданное выражение создания объекта, что такое объект-прототип для создаваемого объекта? Для этого в первую очередь потребуются знания о том, как создавать объекты в JavaScript. Так что давай сделаем это.

Создание объекта с использованием объектных литералов:

Литерал объекта - это выражение в JavaScript. Подобно тому, как каждое выражение оценивает значение или возвращает значение, выражение литерала объекта возвращает вновь созданный объект.

Синтаксис довольно прост. У вас есть некоторые свойства, которые вы хотите назначить новому объекту, и вы уже знаете имена и значения для каждого свойства. Итак, вы составляете список пар имени и значения, разделенного запятыми. Каждая пара имеет имя и значение, разделенные двоеточием (:), и вы заключаете этот список, разделенный запятыми, в фигурные скобки. Поскольку это выражение будет оценивать объект, вы хотели бы зафиксировать этот объект в переменной, чтобы вы могли ссылаться на него позже.

TL; DR? Посмотрите прямо на этот синтаксис, если это было очень скучное описание:

let myObject = {
    name_p1: value_p1, 
    name_p2: value_p2, 
    name_p3: value_p3
}

Итак, myObject теперь имеет три свойства с именами _5 _, _ 6_ и name_p3, значения которых равны value_p1, value_p2, value_p3 соответственно, и эти значения являются допустимыми выражениями JavaScript.

Как правило, если вы не изменили свойство __proto__ на myObject, значение по умолчанию myObject.__proto__ является объектом, на который ссылается prototype свойство объекта Object [1]. Если это вас смутило, взгляните на приведенный ниже фрагмент, который, вероятно, устранит вашу путаницу.

myObject.__proto__ === Object.prototype // => True

[1]: Ниже вы увидите, что Object на самом деле является функцией-конструктором, которая действительно в JavaScript является объектом и называет ее так, как разработан JavaScript, или красота JavaScript, все, что я сказал в предыдущем практическом правиле, остается верным.

Создание объекта с использованием ключевого слова new и вызова конструктора:

Давайте сначала попробуем понять, что такое конструктор. Конструктор похож на любую другую функцию. У него есть параметры, и при вызове он выполняет некоторые операторы, записанные в его теле. Что отличает вызов функции-конструктора, так это то, когда она используется с ключевым словом new. Кроме того, что отличает функцию в JavaScript от функции на других языках, таких как C / C ++ или Java, так это то, что функция в JavaScript является объектом класса Function. Класс [2] в JavaScript означает, что объекты, созданные конкретным классом, будут иметь одинаковые свойства, но значения могут отличаться, т.е. все объекты, принадлежащие классу, имеют один и тот же шаблон или один и тот же производитель. А этого можно добиться с помощью функций-конструкторов!

[2]: Вы можете найти более точное определение класса и конструктора в JavaScript, но пока я бы оставил рабочее определение на этом этапе, которое является правильным, но, вероятно, слабо и будет исправлено позже, если появятся новые предложения / улучшения.

На данный момент достаточно знать, что функции в JavaScript также являются объектами и могут иметь собственные свойства.

Ключевое слово new, за которым следует вызов функции конструктора, создает и инициализирует новый объект.

Эта инициализация выполняется на основе аргумента, который получает функция-конструктор, и определения функции-конструктора.

Создание объекта с использованием вызова конструктора будет выглядеть примерно так:

let myObject2 = new Object(); // => Same as let myObject2 = {};
let arr = new Array(); 
/* => Same as let arr = []; You might be surprised to know that the arrays are also objects of Array class. Strange isn't it? But don't get confused, this is true because almost everything in JS is an object! */
let mihir = new Hooman('Mihir', 'Shah');  

Как правило, объекты, которые создаются с использованием вызова конструктора с ключевым словом new впереди, имеют объект-прототип, ссылающийся на объект, на который указывает свойство prototype функции конструктора.

В некотором смысле это похоже на newObject.__proto__ это Constructor.prototype

Это означает, что,

myObject2.__proto__ === Object.prototype // => True and must be 
// since we are saying new Object() and object literal {} are same
arr.__proto__ === Array.prototype // => True
mihir.__proto__ === Hooman.prototype // => True

Итак, если я хочу, чтобы объект mihir унаследовал некоторые свойства, я бы установил эти свойства для объекта, на который ссылается Hooman.prototype, и все другие экземпляры / объекты класса Hooman будут унаследованы этими свойствами! Звучит круто!

В заключение я упомяну следующий момент, который должен быть довольно очевидным. Как я сказал ранее, функции являются объектами / экземплярами класса Function, и, следовательно, для любой функции его прототипом будет Function.prototype

Array.__proto__ === Function.prototype; // => True
Hooman.__proto__ === Function.prototype; // => True

Создание объекта с использованием Object.create():

create - это свойство объекта Object (также это функция-конструктор, которую мы видели ранее), значение которой является функцией и делает его методом объекта Object. (Я знаю, что это довольно неубедительная и запутанная вещь, но именно это и есть!) Это означает, что мы можем вызывать метод create в любое время, когда захотим.

Как следует из названия, он создает новый объект, но нам не нужно использовать перед ним ключевое слово new. Кроме того, если вы посмотрите документацию MDN (что вам обязательно стоит сделать вместо того, чтобы читать что-то еще вроде этого: P) для Object.create(), вы обнаружите, что она принимает два аргумента. Первый аргумент - это ссылка на объект или литерал объекта, который будет прототипом или родительским объектом нового объекта, который будет создан. Второй аргумент является необязательным и представляет собой propertiesObject, который будет использоваться для установки и инициализации свойств нового объекта. Так, например, это будет выглядеть примерно как фрагмент кода, показанный ниже (на основе документации MDN).

const hoomanObject = {
  printIntroduction: function() {
    console.log("My name is: " + this.firstName + " " + this.lastName");
  }
}
const mihir = Object.create(hoomanObject, 
  {firstName: "Mihir", lastName: "Shah"});
mihir.printIntroduction() // => Logs My name is: Mihir Shah

Заключение:

В этой статье я объяснил, как наследование (которое в некотором роде уникально и известно как прототипное наследование) в JavaScript достигается, когда почти все в JavaScript является объектами. Для этого я объяснил три различных способа создания новых объектов и то, как эти способы принципиально отличаются друг от друга из-за того, как они устанавливают __proto__property для новых объектов, которые являются не чем иным, как родительским объектом, от которого эти новые объекты наследуются. свойства от.

Как только вы освоите наследование таким образом, вас ждет еще много интересных вещей, например, как разрешаются свойства при доступе к объекту, имеющему долгую родословную. Какого черта вы должны использовать прототипное наследование и заботиться о нем? и многие другие вопросы, о которых я тоже не осведомлен!

Использованная литература:

Как я сказал в начале, речь идет о моих двух центах по этой теме, но эти идеи на самом деле не мои, и следующие ресурсы помогли мне понять то, что я только что высказал, и я искренне благодарен соответствующим авторам. Также я хотел бы поблагодарить своих старших коллег из Sprinklr, которые помогали мне изначально подходить к теме и решали все мои вопросы.

  1. JavaScript: полное руководство. Это довольно хорошая книга Дэвида Фланагана, которую необходимо прочитать, чтобы прояснить основы работы JavaScript.
  2. Документация MDN о Object.create()
  3. JavaScript: Ядро. Очень хороший блог и указатель на вопросы, которые я поднял ранее, и я обязан этой статьей этому блогу.

Это моя самая первая статья. Спасибо, что прочитали его, и надеюсь, что вы узнали из него что-то новое. Оставляйте предложения или вопросы, я буду рада их услышать!

Эта история публикуется в Noteworthy, куда ежедневно приходят более 10 000 читателей, чтобы узнать о людях и идеях, формирующих наши любимые продукты.

Подпишитесь на нашу публикацию, чтобы увидеть больше историй о продуктах и ​​дизайне, представленных командой Journal.