Вызов функции — аргументы и это

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

вызовы функций передают два неявных параметра thisи аргументы

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

Аргументы

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

Перегрузка функций — это когда две или более функций могут иметь одно и то же имя, но разные параметры.

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

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

Основная цель использования аргументов — позволить нам получить доступ ко всем аргументам, которые были переданы функции, независимо от того, связан ли аргумент с параметром функции.

Аргументы как псевдоним для параметров функции

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

  • Избегайте псевдонимов

В JavaScript есть способ отключить псевдонимы аргументов с помощью строгого режима.

Этот

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

Способ вызова функции оказывает огромное влияние на то, как работает код внутри, в первую очередь на то, как устанавливается параметр this (контекст функции). Мы можем вызывать функцию четырьмя способами.

  • Как функция: hello ()
  • Как метод: hello.name()
  • Как конструктор: new Person ()
  • С помощью функций применитьили вызвать методы: hello.call(Person) hello.apply(Person)

Вызов как функция

Этот тип вызова возникает, когда функция вызывается с помощью оператора ( ), вот несколько примеров

Здесь контекст функции (это ключевое слово) может быть двумя вещами:

  • Нестрогий режим: глобальный контекст (объект окна)
  • Строгий режим: не определено

Вызов как метод

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

Когда мы вызываем функцию как метод объекта, этот объект становится контекстом функции (ключевое слово this) и доступен внутри функции через this параметр

Несмотря на то, что одна и та же функция -context- используется во всех вызовах, контекст функции (this) изменяется в зависимости от того, как вызывается context

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

Вызов в качестве конструктора

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

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

Функция конструктора используется для создания нескольких объектов.

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

  1. Создается новый пустой объект
  2. Новый объект передается конструктору как параметр this и, таким образом, становится контекстом функции конструктора.
  3. Новый сконструированный объект возвращается как значение нового оператора.

Возвращаемые значения конструктора

Мы знаем, что конструкторы предназначены для инициализации новых объектов, а новый объект является результатом вызова конструктора (через оператор new)

Что происходит, когда конструктор возвращает собственное значение?

  • Примитивные значения

Когда конструктор возвращает примитивное значение, это не влияет на поведение кода.

Если мы вызовем это как функцию, она вернет «солнце», как и ожидалось.

Если мы вызываем его как конструктор, новый объект создается и возвращается

  • Значения объекта

Если конструктор возвращает объект, этот объект возвращается как значение новоговыражения, а объект, переданный как‘this’ конструктору, отбрасывается.

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

Вопросы кодирования для конструкторов

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

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

Мы можем вызвать Person как простую функцию, но свойство exist будет создано в окне в нестрогом режиме.

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

Применить и вызвать методы

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

Мы делаем это с помощью одного из двух методов, существующих для каждой функции: apply и call

Применить

Чтобы использовать метод применения, мы передаем два параметра

  • Объект, который будет использоваться в качестве контекста функции (этот)
  • Массив значений, которые будут использоваться в качестве аргументов вызова.

Позвонить

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

Устранение проблемы контекстов функций

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

Когда вызывается обработчик события, контекст функции (this) устанавливается на объект, к которому событие было связано.

Если мы вызовем функцию как метод, контекстом функции (this) будет кнопка, потому что она вызывается как метод для объекта кнопки

Если мы используем Систему обработки событий, Браузер определяет контекст функции (this) как целевой элемент события, который вызывает контекст должен быть HTML-элементом ‹button›

Вынуждает нас устанавливать наш метод щелчка не на том объекте!

Вы видели распространенную проблему, которая возникает при работе с контекстом функции в JS, в функции обратного вызова (например, в обработчиках событий), контекст функции может быть не совсем таким, как мы ожидаем, мы можем использовать вызов или применить к обойти это

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

Стрелочныефункции для решения контекстов функций

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

Стрелочные функции не имеют собственного значения this, они запоминают значение параметра this во время своего определения.

Единственным изменением является замена функции на стрелочную функцию, потому что стрелочные функции запоминают значение этого параметра во время их создания.

В нашем случае функция стрелки была создана внутри функции-конструктора, где параметр this — это вновь созданный объект (объект-кнопка).

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

ВНИМАНИЕ! Функции и объекты со стрелками

Поскольку значение this подбирается в момент создания стрелочной функции, это может привести к странному поведению.

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

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

Метод привязки

Каждая функция имеет доступ к методу bind, который создает новую функцию.

Эта новая функция имеет то же тело, но контекст ее функции (this) всегда привязан к переданному объекту, независимо от того, как мы ее вызываем.

Вызов метода привязки не изменяет исходную функцию, он создает новую функцию, как показано в примере, сохраняя ее в переменной (активировать)

Разница между вызовом, применением и привязкой

  • Используйте .bind(), если вы хотите, чтобы эта функция позднее вызывалась с выбранным контекстом функции, полезно в событиях.
  • Используйте .call() или .apply(), если вы хотите вызвать функциюнемедленно и изменить контекст.

Call & Apply немедленно вызвать функцию

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