Прежде чем приступить к следующей практике, нам надо освоить пару теоретическим тем, а точнее что такое стрелочные функции, метод forEach и JSON. Начнем со стрелочных функций.
Стрелочные функции – это более краткий, удобный способ объявления функций, который появился в 6-ой версии языка JavaScript. Синтаксически она выглядит так:
Если у стрелочной функции одни параметр, то скобки можно опустить:
Если функция возвращает одно выражение, фигурные скобки и оператор return можно также опустить:
Давайте напишем простой пример:
Имя функции будет квадратЧисла. далее пишем один параметр, затем указываем стрелку с помощью знака равно и угловатой скоби, и функция будет возвращать значения параметра умноженного на него же. Проверяем, все работоает.
У стрелочных функции есть свои особенности, которые отличают их от обычных функции. И чтобы поговорить о первой особенности, нам надо освоить новый объект, который используют внутри функций – это Arguments. По сути, данный объект хранит внутри себя все аргументы, которые вы ввели в функцию. Давайте напишем простой пример.
Вы можете спросить, а с чего это Arguments это объект, если он похож на массив? Вот здесь вместо ключей порядковые номера. Причина связана с историческим контекстом. Его придумали в 1995 году, когда еще объекты и массивы в языке не выглядели так как они выглядят сейчас. Сейчас мы тоже не можем назвать объект Arguments массивом, так как ему недоступны методы, которые доступны для массивов, например метод forEach, который мы изучим сегодня. Получается Объект Arguments придумали очень давно, правила в JavaScript не единожды обновлялись, но данный объект остался в своем исходном виде, что и делает его отличительным от нынешних объектов.
Теперь переходим к стрелочным функциям. Всю эту тему про объект Arguments я начал для того, что бы сказать – стрелочные функции не поддерживают данный объект, в отличии от обычных функций. Это была первая особенность, которая отличает стрелочные функции от обычных функций.
Но как же обойти отсутствие arguments в стрелочных функциях. Для этого вы можете воспользоваться оператором распространения. Помните мы использовали оператор распространения, чтобы скопировать значения одного объекта в другой. Но оператор распространения можно использовать в функциях. И все аргументы, что вы передадите, упакуются в массив с именем параметра. Давайте снова попрактикуемся.
Вот и таким образом мы обошли ограничение стрелочных функций. Теперь перейдем к следующему отличию стрелочных функций от обычных. И это связано с ключевым словом this. Как вы помните, в обычных функциях, или методах ключевое слово this ссылается на объект, которому принадлежит метод. Давайте рассмотрим такой пример.
В данном случае ничего сложного, ключевое слово this вызывается внутри метода obj, а значит будет ссылаться на этот объект. А если м напишем так:
Т.е. здесь функция forThis не является методом объекта obj, так как мы не можем обратиться к ней напрямую через точку. В таком случае ключевое слово this будет ссылаться на глобальный объект window, и искать ключ level у глобального объекта, которого естественно нет. Т.е. если функция не является методом какого-либо созданного вами объекта, то ключевое слово this внутри этой функции будет ссылаться на глобальны объект (Но случае событий, которые отслеживаются с помощью метода AdEventListener, ключвое слово this будет ссылаться на элемент который вызывал это событие. Это мы увидим на следующей практике). Итак, возвращаемся к нашему примеру, так как свойства level у объекта window нет, мы можем обратиться к такому свойству объекта window которое у него есть, например свойство document.
B теперь если мы вызовем свойство fun объекта obj то она вернет объект документа в виде DOM.
В стрелочной функции ключевому слову this присваивается ссылка на родительский элемент в момент вызова. Что это значит. Давайте чуть изменим наш объект:
Если у стрелочной функции нет параметров, то мы обязаны указать пустые скобки. Видите как более компактно стала выглядеть функция. Теперь запустим этот метод. Как видите, вернулось значение undefined. Дело в том, как я уже сказал, ключевому слову this в стрелочной функции присвается ссылка только в момент вызова, и ссылка эта будет ввести на родительский элемент. Т.е. когда мы вызвали функцию fun, ключевое слово this, давайте представим, будто бы вышло из этого метода и посмотрела внутри какого объекта находится эта инструкция. Она находится внутри объекта window, значит объект window является родительским, и ссылка в ключевом слове this будет ввести на объект window. А так как у объекта window нет ключа level, то функция вернет undefined. Поэтому стрелочные функции не рекомендуется использовать как методы объекта. Вы можете подумать, раз в этой строчке присутствует obj, то и функция fun находится как-бы внутри него в этой строчке. Но нет, для транслятора, слово obj , точка и имя функции, все вместе это как бы адрес как найти функцию, он ее находит в в этой строчке вызывает. А ключевое слово this уже смотрит внутри чего состоялся этот вызов, т.е. внутри какого объекта находится эта строчка.
А давайте теперь напишем так.
Пишем ключевое слово this. В данном случае функция Person является методом объекта window а значит в this будет ссылка на объект window. И таким образом мы создадим ключ name у объекта window. Далее напишем функцию SetInterval и в первом параметре будет стрелочная функция которая будет просто выводить name. Запускаться стрелочная функция будет каждую секунду.
Теперь запустим эту функцию:
В данном случае, ключевое слово this находится внутри setInterval. Ключевое слово this смотрит, где находится сейчас эта функция (ему все равно, что функция setInterval является методом window, ключевому слову this важно только где сейчас она находится) она находится внутри метода Person, т.е. Person это родительский элемент. Но Person это метод а не объект в чистом виде (говорю в чистом виде, так как в javascript все по сути всё является объектами). Итак Person это не объект в чистом виде а метод объекта window, значит вот он тот самый объект, на который должно ссылаться ключевое слово this. А Person это метод какого объекта – в данном случае – это метод объекта window. Значит this будет ссылаться на объект window.
Помните, создавали объекты с помощью ключевого слова new. Так вот, если мы после ключевого слова new укажем обычную функцию, то функция превратится в конструктор, и создаст объект с ключами указанные в функции, в нашем случае – это будет ключ name. Давайте создадим объект. Если мы создаем его без переменной, то это будет безымянный объект. Запускаем.
Так как в данном случае , функция превращается в конструктор, то setInterval, который запускает стрелочную функцию, находится в данный момент внутри безымянного объекта, а значит this ссылается на этот безымянный объект. Чтобы в этом убедиться давайте поменяем значение ключа namе для объекта window. И как видите, у нас все равно выводится имя Saida.
Мы также можем создать именной объект.
И будет выводится имя Mira.
Также стрелочные функции не могут выступать в качестве конструкторов. На этом отличия практически заканчиваются. Я говорю практически, так как чтобы изучить еще два отличия надо будет освоить еще новые большие темы, но я не хочу затягивать сильно это видео, так что изучим мы их уже на следующих уроках.
Теперь переходим к следующей теме, это встроенный метод массивов, который называется forEach. Благодаря ему мы можем применить любую функцию ко всем элементам массива. Синтаксис этого метода выглядит так:
Где array – это массив, на котором вызывается метод forEach. Callback – функция, выполняемая для каждого элемента массива. Эта функция принимает три аргумента:
currentValue — текущий обрабатываемый элемент массива.
index (необязательный) — индекс текущего элемента.
array (необязательный) — массив, на котором был вызван метод. Зачем он нужен мы скоро рассмотрим.
thisArg (необязательный) — это значение, используемое в ключевом слове this при вызове функции callback, если ключевое слово this есть внутри этой функции. Мы тоже этот параметр скоро рассмотрим. Метод forEach не изменяет массив, он просто работает с его значениями.
Итак, давайте создадим простой пример. В консоль лог наберем шаблонный текст.
И вот метод вывел все индексы и значения массива один за другим. Если мы хотим еще в каждом значении выводить весь массив, то можно воспользоваться третьим параметром, назовем его array.
Название функции callback можно не использовать. А вообще здесь удобней пользоваться стрелочной функцией.
Так, давайте теперь разберемся, зачем нужен параметр thisArg. Рассмотрим такой пример.
Т.е. здесь функция callback сработает 3 раза, так как у массива 3 значения. И каждую итерацию callback значению ключа count будет прибавляться 1. Получается, когда выполнится метод ForEach ключ каунт будет равен 3. Давайте в этом убедимся.
А что если у нас много объектов класса класса Counter, и мы хотим вызывать метод increase разных объектов класса Counter. Мы конечно можем менять название объекта здесь или заменить имя объекта на ключевое слово this, и в параметре thisArg писать имя объекта, тогда this будет ссылаться на этот объект.
Если мы будет использовать стрелочную функцию, то параметр thisArg указывать не надо, так как стрелочная функция, при выполнении метода forEach ключевое слово this будет искать метод increment у массива increments.
Также метод forEach можно применять при работе с объектами, но перед этим надо преобразовать его в массив, с помощью метода объекта Object, который называется entries. Давайте создадим объект:
Если мы сейчас нажмем Enter то метод entries вернет нам двумерный массив. Так как он возвращается массив, то мы можем применbть к нему метод forEach. В качестве функции callback булет использовать стрелочную функцию. Итак, мы знаем, что в качестве значения будут массивы из двух значений. Мы можем этим значения дать имена, Для этого укажем в параметре currentValue что мы получим массив со значениями, где первое значение будет называться key, а второе value. Этот способ, когда мы в current value пишем массив со значениями, называется деструктуризация массива, и обязательно, даже не смотря на то что это один параметр, должен находится внутри скобок в стрелочной функции. В теле функции пишем console.log так как метод forEach ничего в консоль не возвращает.
Нам осталось рассмотреть последнюю тему, это JSON.
JSON – это легкий формат обмена данными, который легко читается и записывается человеком, а также легко анализируется и генерируется машиной. Расшифровывается как JavaScript Object Notation, т.е. своими словами можно перевести как Запись в виде JavaScript объекта. Т.е. внутри файла с расширением json вся информация будет записана в виде javaScript объекта и выглядеть примерно так:
Получается у нас есть ключи, которые в отличие от обычного JavaScript объекта обязаны быть внутри кавычек, а в значениях у нас могут быть строки, числа, булевы значения, массивы и объекты.
JSON не является частью JAvaScript и его можно использовать с помощью других языков программирования. Просто JavaScript сильно повлиял на его появление.
Как у других языков, у JavaScript есть методы для работы с JSON – это JSON.stringify() и JSON.parse().
Давайте их изучим, начнем с Stringify. Данный метод позволяет преобразовать объект в строку формата JSON. Синтасически он выглядит так:
JSON.stringify(obj, replacer, space).
Обязательным из параметров является только object, т.е. объект который вы хотите преобразовать в JSON строку. Сюда в качестве аргумента можно добавить функцию или массив, которые будут фильтровать свойства объекта. Мы скоро такой пример рассмотрим.
space – это строка или число для вставки отступов в тексте JSON.
Давайте рассмотри простой пример.
Как видите, ничего сложного. Давайте теперь используем параметр replacer. Допустим мы не хотим чтобы в JSON попал возраст, для этого напишем функцию.
При преобразовании в JSON в функцию будут передаваться ключ и значение. Укажем их в параметрах. Теперь если ключ равен слову возрвст, то вернем undefined. Это сообщит методу stringify, что данный ключ не надо преобразовывать. А если ключ не равен слову возраст, то вернем его значение.
Выводим. И вот, мы исключили ключ возраст в JSON.
Чтобы вывод красиво смотрелся, мы можем воспользоваться третьим параметром, благодаря которому, мы добавим 2 знака пробел между ключами.
Как видите, в этих местах добавились пробелы, и также теперь каждый ключ находится на отдельной строчке. Это происходит автоматически, когда мы добавляем любой аргумент не равный нулю. Если мы добавим строку, то вместо пробела, будет эта строка.
Метод Parse делает все тоже самое только наоборот, текст в формате JSON переводит в объект.
У данного метода есть еще один необязательный параметр, это revier, благодаря которому можно фильтровать ключи из текста JSON. Например, мы можем засекретить Город.
Давайте здесь уже будем использовать стрелочную функцию
На этом урок заканчивается, до встречи на следующих уроках.