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

Те, кто пропустил первую часть этого руководства, могут получить к нему доступ по ссылке ниже.



Обзор объектов JS

В JavaScript объект описывается как набор связанных данных и / или функций. Данные объекта называются его property, тогда как функция, объявленная внутри объектов, называется method.

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

Мы назовем наш объект book и дадим ему свойство с именем «name» и соответствующее значение, мы также дадим ему второе свойство с именем «author» и соответствующее значение.

Наконец, мы определим метод под названием getBookDetails, который будет возвращать строку, которая печатает - ›
« Книга «Красноречивый JavaScript: современное введение в программирование» написана Марин Хавербеке »

Пример определения объекта

Давайте рассмотрим наш пример

  • Мы определили наш объект, просто присвоив ему имя и пару пустых фигурных скобок, то есть {}
  • Объекты состоят из пар ключ / значение, и мы создали нашу, используя «точечную нотацию», посредством чего мы определили имя свойства и немедленно присвоили ему соответствующее значение, например book.author = “Marijn Haverbeke
  • Мы создали метод и назначили ему функцию. Ключевое слово «this» относится к имени объекта, то есть book

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

Мы рассмотрим следующие темы:

  • Конструкторы объектов JS
  • Методы объекта ES5
  • Классы и методы ES6
  • Получить и установить методы
  • Функции генератора

Конструкторы объектов JS

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

Что происходит, когда я хочу добавить вторую, третью или даже четвертую книгу?. Мы могли бы определить новые объекты и назвать их book2, book3, book4 и т. Д.
Это не лучшее решение, поскольку мы повторяем один и тот же код несколько раз раз, а в JS всегда хочется придерживаться СУХИХ принципов.

Кроме того, что бы вы сделали, если бы дали добавить 120 книг?

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

Пример использования функции конструктора объектов

Важные замечания о конструкторах объектов JS

  • Убедитесь, что имя вашего конструктора всегда начинается с заглавной буквы. В данном случае мы назвали его Book, это не обязательно, но это отличное соглашение об именах, которое используют разработчики JS, чтобы отличать конструкторы объектов от обычных функций.
  • В строках 3–5 мы просто создаем экземпляры наших переменных, то есть устанавливаем их значения так, чтобы мы не возвращали undefined, когда мы вызываем имя свойства нашего объекта.
  • Теперь, когда у нас есть конструктор («план»), мы можем добавить столько книг, сколько захотим, используя ключевое слово new с именем нашего конструктора, а затем передавая некоторые параметры для имени и автора.
  • Метод getBookDetails() можно вызывать несколько раз из одного объявления. Однако обратите внимание, что определение метода непосредственно в прототипе - гораздо лучшее решение, поскольку мы не создаем новый экземпляр метода каждый раз, когда создаем новую книгу, мы сделаем это в следующем разделе

Методы объекта ES5

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

Давайте изучим наш код

  • Использовалась буквальная строка шаблона, т.е. мы удалили кавычки и заменили их обратными галочками, а также встроили наши переменные в более сжатой форме.
  • Метод getBookDetails был напрямую добавлен к прототипу объекта вместо его определения в конструкторе функции, в результате чего новый экземпляр метода должен был создаваться для каждой новой книги, которую мы добавляем. Если мы добавим 1000 книг, это означает, что у нас будет 1000 экземпляров этого метода, но поскольку мы переместили его в прототип объекта, это означает, что мы объявляем его только один раз, и мы можем использовать его несколько раз без необходимости создавать его копии каждый раз, когда мы используем new ключевое слово.
  • Вызывая имя нашего объекта и метод, мы по-прежнему получаем точно такие же результаты, как и раньше, а повышение производительности, о котором мы только что говорили, происходит под капотом.

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

Методы класса ES6

До сих пор мы изучили, как писать методы с использованием классических выражений функций ES5, а также рассмотрели, как добавить метод к прототипу объекта. В этом разделе руководства мы собираемся добавить новый метод с именем getBookCost в наш конструктор функции, используя синтаксис ES6.

При написании методов ES6 следует отметить несколько ключевых отличий.

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

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

Подробнее о занятиях читайте в этой очень короткой статье.

Получить и установить функции

В Javascript существуют геттеры и сеттеры. Если у вас есть опыт использования других объектно-ориентированных языков программирования, таких как Java, вы найдете эту концепцию очень похожей на то, что вы уже знаете.

Проще говоря, геттеры позволяют нам «получать» значение определенного свойства, в то время как сеттер позволяет нам «устанавливать» значение определенного свойства. В синтаксисе определения геттеров и сеттеров используется синтаксис объектного литерала. Давайте посмотрим на пример.

В приведенном выше примере мы сделали следующее

  • Мы определили метод получения с именем movieDetails, который просто возвращает строку текста, чтобы дать нам более подробную информацию о нашем фильме.
  • Чтобы вызвать геттер, мы назвали имя объекта, то есть фильм, использовали точечную нотацию и поместили наше имя геттера, обратите внимание, что мы НЕ использовали круглые скобки.

Давайте посмотрим на тот же пример, но на этот раз мы собираемся включить сеттер.

В приведенном выше примере мы должны принять во внимание следующее

  • Мы определили сеттер с именем actors.. Сеттер примет параметр имени, который мы добавляем в наш пустой массив с именем cast.
  • Мы инициализируем наши значения для установщика, вызывая имя нашего объекта, то есть movie, используя точечную нотацию и вызывая имя свойства, которое мы устанавливаем, в данном случае это имя нашего установщика actors
  • Затем мы вызываем наш геттер movieDetails, как в предыдущем примере, но на этот раз он напечатает строку, которая включает в себя приведение ролика, которое мы определили.

Геттеры и сеттеры, которые мы использовали выше, также могут использоваться прямо внутри наших классов ES6. Они хороши для добавления уровня абстракции. В приведенном ниже примере мы будем использовать геттер, чтобы получить цену элемента, которая будет рассчитана в метод называется calcCost.

Есть гораздо более умные способы использования геттеров и сеттеров при работе с объектами JavaScript. Например, вы можете использовать Object.defineProperty для достижения тех же результатов, что и выше, но моя цель в этом руководстве - сосредоточиться на простых или общие способы использования, а не исчерпывающее руководство, так как это было бы слишком длинным и, возможно, запутало бы некоторых читателей. Чтобы получить гораздо более глубокое понимание геттеров и сеттеров, я бы рекомендовал взглянуть на эту статью для справки, а также на официальную документацию.



Функции генератора

В JavaScript ES6 в спецификацию был добавлен новый тип функций. Этот тип функций обычно известен как функции генератора или просто генераторы и имеет некоторые ключевые отличия от обычных функций JS, с которыми мы работали до этого. точка.

Чтобы определить генератор функций, мы следуем синтаксису, аналогичному тому, как мы определяем обычные функции, но ключевое отличие состоит в том, что мы добавляем звездочку вскоре после ie (function* {//code goes here}), и таким образом JavaScript будет знать, что он должен создать функцию генератора. вместо обычной функции.

Использование приведенного выше синтаксиса не только определяет функцию генератора, но также возвращает объект Generator. Существует альтернативный синтаксис, в котором вы также можете создать их с помощью GeneratorFunction Конструктор, но известно, что он менее эффективен, чем первый метод, поэтому мы будем использовать function* во всех наших примерах.

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

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

Давайте рассмотрим наш пример, чтобы полностью понять, как он работает:

  • Сначала мы определили функцию генератора с именемtakeOff.. Следует отметить, что мы всегда добавляем звездочку (*) после ключевого слова function.
  • В теле функции мы использовали ключевое слово yield , и его цель - дать нам возможность приостанавливать и возобновлять выполнение нашей функции.
  • Затем мы определили новое выражение функции с именем countDown, которое просто содержит объект, возвращенный функцией генератора, которую мы определили выше, так что мы можем легко итерировать его.
  • После этого мы начинаем перебирать countDown, используя метод next().
  • Метод next() возвращает объект со свойством value, содержащим полученное значение, и свойство done, которое указывает, выдал ли генератор свое последнее значение или нет.
  • Когда следующий метод, наконец, возвращает значение undefined, а для значения done установлено значение true, это означает, что мы выполнили итерацию по всему объекту
    т.е. {value: undefined, done: true}

Второй пример похож на первый, но следует отметить несколько моментов:

  • Мы включили цикл в наш генератор, чтобы перебирать массив javascriptFrameworks
  • Мы присвоили нашему возвращенному генератору константу listFW
  • Мы, как и раньше, перебираем каждый из объектов, используя метод next(), но на этот раз нас интересует только получение свойства ‘value’ из нашего генератора, а затем мы объединяем его с помощью строковых литералов для вывода разных сообщений при каждом вызове.
    т.е. <name> is very popular in the JS ecosystem
  • Если бы мы добавили еще один вызов к нашему генератору, мы бы получили "undefined очень популярен в экосистеме JS". Чтобы избежать этого, мы можем просто выполнить условную логику, чтобы проверить, соответствует ли значение свойства done установите значение true и вместо этого напечатайте что-нибудь еще, например «Список завершен».

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

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

Резюме

Мы рассмотрели множество различных функций в этой части 2 статьи, и тем из вас, кто читал ее из части 1, я очень благодарен за ваше терпение и то, что вы нашли время прочитать оба руководства. Если вы сочтете это полезным пожалуйста, не стесняйтесь делиться или хлопать, и вы также можете оставить несколько комментариев ниже, если у вас есть какие-либо отзывы, предложения, критика и т. д. (все приветствуются), и я обязательно отвечу.