Большая пятерка — шаблоны создания экземпляров в Javascript

Прежде чем мы что-либо обсудим, важно определить пару ключевых терминов, которые помогут нам в прочтении этой статьи, а именно «экземпляр» и «экземпляр». Экземпляр — это то, что представляет или является примером чего-то другого, а экземпляр — это создание экземпляра. Поэтому, основываясь на приведенных выше определениях, мы можем с уверенностью заключить, что шаблон инстанцирования — это метод создания экземпляра чего-либо. Что именно мы создаем? Объекты!

Я уверен, вы уже знаете, что объект — это сложная структура данных, которая служит способом моделирования объектов реального мира в Javascript. Каждый объект реального мира имеет состояние и поведение(я), которые представлены свойствами и методами объекта JS соответственно. При создании программы наступит момент, когда вам нужно создать любое количество экземпляров объекта. Вместо того, чтобы вручную создавать каждый объект один за другим, шаблоны создания экземпляров повышают эффективность нашего кода за счет использования функции конструктора, которая определяет свойства и методы объекта только один раз, для которых мы позже предоставляем значения во время создания экземпляра. Чтобы уточнить, цель функции-конструктора — инициализировать объект.

Теперь, когда у нас есть фундаментальное понимание того, что такое шаблоны создания экземпляров и почему мы их используем, давайте углубимся и откроем для себя пять шаблонов создания экземпляров, с которыми вы столкнетесь при работе с объектами в Javascript, перечисленные ниже.

  1. Функциональный
  2. Функциональный общий
  3. Прототип
  4. Псевдоклассический
  5. ES6 Псевдоклассика

Здесь следует отметить одну вещь: мы будем использовать Pascal, а не Camel в качестве нашего соглашения об именах для объявления наших функций конструктора и классов. Это следует делать всегда.

Функциональный

Начнем с функционального шаблона инстанцирования. Прежде чем двигаться дальше, найдите время, чтобы просмотреть приведенный ниже фрагмент кода и попытаться понять, что происходит….

Выше вы увидите, что наша функция-конструктор состоит из нескольких простых шагов. Литерал пустого объекта назначается personObj, ему задаются его свойства (имя, возраст и favColor) и единственный метод (приветствие), и, наконец, он возвращается. Довольно просто, правда?

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

Про

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

Минусы

Одна вещь, которую вы, возможно, не заметили, заключается в том, что с этим шаблоном каждый экземпляр Person будет создавать новую функцию «приветствия». Если это не кажется серьезным недостатком, представьте, что ваша программа должна была создать сотню экземпляров… тысячу… теперь представьте, что у вашего объекта гораздо больше методов! По мере того, как количество экземпляров становится все больше и больше, вы начинаете занимать ненужное место в памяти для размещения каждой функции. Входит функционально-совместно.

Функционально-общий

Как и раньше, найдите время, чтобы взглянуть на приведенный ниже фрагмент кода и указать на отличия, которые вы видите в фрагменте кода Functional.

Вы должны были заметить два отличия. Во-первых, наша функция «приветствие» переместилась за пределы нашей функции-конструктора в объект с именем «sharedMethods». Во-вторых, это использование «_.extend» в строке 43. Extend — это функция подчеркивания, которая принимает два параметра, первый — это объект, в который мы будем копировать свойства, а второй — объект, из которого мы будем получать свойства. для копирования. Обратите внимание, что наши методы будут скопированы по ссылке, а НЕ ДУБЛИРОВАНЫ.

Про

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

Против

Хорошо, мы освободили кучу места! При чем тут афера?! К сожалению, есть недостаток использования функции расширения. Хотя наши экземпляры объектов сохраняют ссылки на методы, размещенные в «sharedMethods», они будут иметь ссылки только на методы, которые присутствовали во время расширения. Поэтому, если мы решили добавить метод в sharedMethods, все экземпляры, созданные ранее, не будут иметь ссылки на добавленный метод. Протопал в помощь!

Прототип

Вы уже знаете процедуру, посмотрите фрагмент кода ниже.

Еще раз, здесь есть только небольшое изменение, обратите внимание, чему присваивается наша константная переменная personObj. Object.create() — отличное решение нашей предыдущей проблемы, созданной функцией расширения, где ранее созданные экземпляры не имеют ссылок на недавно добавленные методы нашего объекта sharedMethods.

Взятый непосредственно из MDN, «метод Object.create() создает новый объект, используя существующий объект в качестве прототипа вновь созданного объекта». Проще говоря, Object.create() создает мост между каждым экземпляром и общими методами. Когда свойство/метод не может быть найдено в экземпляре, Javascript проходит по этому мосту и проверяет общие методы.

Про

В отличие от функционально-совместно используемых, при обновлении sharedMethods ВСЕ экземпляры имеют доступ к обновлениям.

Против

Я не обязательно вижу здесь недостаток, но наш следующий шаблон абстрагирует для нас несколько фрагментов кода. Давайте проверим это.

Псевдоклассический

Вы должны автоматически заметить две вещи в нашей функции-конструкторе; объявление и возврат нашего объекта, казалось бы, исчезли! Ух ты, строка 41 выглядит прикольно, а слово «новый» появилось перед вызовом нашего конструктора.

Во-первых, исчезновение объявления/возврата нашего объекта и появление «нового» идут рука об руку. Новое ключевое слово делает несколько важных вещей…

  1. Инициализирует пустой объект;
  2. Связывает «это» с указанным выше объектом;
  3. Возвращает объект;

Пункты 1 и 3 — вот почему мы избавились от объявления объекта и возврата в нашем конструкторе.

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

ES6 Псевдоклассика

В ES6 появилось ключевое слово class, которое служит функцией и помогает немного повысить удобочитаемость. Вы заметите, что мы по-прежнему используем функцию-конструктор и ключевое слово new для создания нашего объекта, как и в псевдоклассическом, но конструктор находится внутри класса. Но в отличие от Pseudoclassical, мы больше не прикрепляем наш метод к свойству .prototype «Person», вместо этого мы помещаем его непосредственно в наш класс.

Про

Классы повышают читаемость наших кодов!

Против

Согласно rajaraodv (https://medium.com/@rajaraodv/is-class-in-es6-the-new-bad-part-6c4e6fe1ee65), Class может ухудшить ситуацию, потому что официальный «Class ES6 это просто синтаксический сахар, технически и концептуально неточный (т.е. это ложная реклама или повод для большей путаницы).

Вывод

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