Давайте разоблачим мифы об операторе new в JavaScript

Давайте разоблачим мифы об операторе new в JavaScript

От автора: в минувшие выходные я закончил работу над JavaScript: The Hard Parts Уилла Сентанса. Это может показаться не самым великолепным способом провести выходные, но я действительно развлекся и расслабился, заканчивая курс. Он коснулся функционального программирования, функций более высокого порядка, замыканий и асинхронного JavaScript.

Для меня основной темой курса было то, как он расширил подходы JavaScript к объектно-ориентированному программированию (ООП) и демистифицировал магию оператора new. Теперь у меня есть хорошо продуманное понимание того, что происходит под капотом, когда используется оператор new JavaScript.

Объектно-ориентированное программирование в JavaScript

Объектно-ориентированное программирование (ООП) — это парадигма программирования, основанная на концепции «объектов». Данные и функции (атрибуты и методы) объединены внутри объекта.

Объект в JavaScript представляет собой набор пар ключ-значение. Эти пары ключ-значение являются свойствами объекта. Свойством может быть массив, функция, сам объект или любой примитивный тип данных, такой как строки или целые числа.

Какие методы мы используем в нашем инструменте JavaScript для создания объекта?

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

Вариант 1 – обозначение объектного литерала

Объектный литерал JavaScript — это список пар имя-значение, завернутый в фигурные скобки. В приведенном выше примере создается объект user1, и связанные с ним данные хранятся внутри него.

Вариант 2 —  Object.create()

Методы Object.create принимают 2 аргумента:

proto: объект, который должен быть прототипом вновь созданного объекта. Это должен быть object или null.

propertiesObject: свойства нового объекта. Необязательный аргумент.

По факту, вы передаете в Object.create объект, который вы хотите наследовать, и он возвращает новый объект, который наследуется от объекта, который вы ему передали.

Варианты создания базового объекта выше повторяются. Для этого требуется, чтобы каждый из них был создан вручную.

Как это обойти?

Решения

Решение 1 – генерация объектов через функцию

Простое решение – написать функцию для создания новых пользователей.

Чтобы создать пользователя, вы должны ввести информацию в параметры функции.

Однако функция increment в приведенном выше примере является только копией исходной функции increment. Это не очень хороший способ написать код, так как любые потенциальные изменения в функции должны выполняться вручную для каждого объекта.

Решение 2 – использование прототипной природы JavaScript

В отличие от объектно-ориентированных языков, таких как Python и Java, JavaScript не имеет классов. Он использует концепцию прототипов и цепочек прототипов для наследования.

Когда вы создаете новый массив, вы автоматически получаете доступ к встроенным методам, таким как Array.join, Array.sort и Array.filter. Это связано с тем, что объекты массива наследуют свойства от Array.prototype.

Давайте разоблачим мифы об операторе new в JavaScript

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

Когда был создан объект user1, была создана цепочка прототипов с функцией userFunction.

Когда user1.increment () находится в стеке вызовов, интерпретатор будет искать user1 в глобальной памяти. Затем он будет искать функцию increment, но не найдет ее. Интерпретатор рассмотрит следующий объект в цепочке прототипов и найдет там функцию increment.

Решение 3 – new и this

Давайте разоблачим мифы об операторе new в JavaScript

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

Когда мы вызываем функцию конструктора с помощью new, мы автоматизируем следующие действия:

создание нового объекта

привязку this к объекту

Объектом прототипа функции конструктора становится свойство __proto__ нового объекта

Возвращается объект из функции

Это фантастика, потому что автоматизация приводит к менее повторяемому коду!

Используя шаблон прототипа, каждый метод и свойство добавляются непосредственно на прототипе объекта.

Интерпретатор пробежит по прототипной цепочке и найдет функцию increment под свойством прототипа User, который сам по себе также является объектом с информацией внутри него. Помните — все функции в JavaScript также являются объектами. Теперь, когда интерпретатор нашел то, что ему нужно, он может создать новый локальный контекст выполнения для запуска user1.increment ().

Замечание: Разница между __proto__ и прототипом

Если вы уже запутались в __proto__ и прототипе, не волнуйтесь! Далеко не вы один запутались. Прототип — это свойство функции-конструктора, которое определяет, что станет свойством __proto__ на построенном объекте. Таким образом, __proto__ является созданной ссылкой, и эта ссылка называется прототипом цепной связи.

Решение 4 – синтаксический сахар ES6

Давайте разоблачим мифы об операторе new в JavaScript

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

В решении 3 соответствующие методы были точно реализованы с использованием User.prototype.functionName. В этом решении те же результаты достигаются, но синтаксис выглядит более чистым.

Заключение

Теперь мы узнали больше о различных вариантах, которые мы имеем в JavaScript для создания объектов. Хотя объявления классов и оператор new относительно просты в использовании, важно понять, что автоматизировано.

Повторим, следующие действия автоматизируются при вызове функции конструктора с помощью new:

создание нового объекта

привязку this к объекту

Объектом прототипа функции конструктора становится свойство __proto__ нового объекта

Возвращается объект из функции

Автор: Cynthia Lee

Источник: //medium.freecodecamp.org/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: