JavaScript | Как привязать объект контекста вызова функции?

JavaScript | Как привязать объект контекста вызова функции?

Как вызывать функцию, в теле которой есть ключевое слово this, в контексте какого-то объекта?

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

Но бывают ситуации, когда нужно протестировать какой-то функционал алгоритма и при это не используя обновление свойств класса через свойство prototype. Порой нужно просто написать функцию, которая в своём теле использует ключевое слово this. Такая функция будет доступна на самом верхнем уровне видимости и её имя будет одним из свойств глобального объекта.

Если она будет вызываться вне какого-то конкретного объекта, а сама по себе, то вместо this мы будем получать сам глобальный объект. В случае с клиентскими браузерами это будет объект window, а в случае с серверными приложениями — это будет объект global.

Если внутри тела функции мы обращаемся к таким свойствам this, которых нет у глобального объекта, то мы не получим желаемого результата, а 100% получим ошибку. В этом и кроется проблема. Как исправить эту проблему?

 

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

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

Каждый функциональный объект JavaScript имеет 6 свойств:

  1. apply(thisArg, argArray)
  2. bind(thisArg, …args)
  3. call(thisArg, …args)
  4. constructor
  5. toString()
  6. [@@hasInstance ](V) или литерально «[Symbol.hasInstance]«

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

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

Метод call() привязывает объект контекста для функции и СРАЗУ вызывает её.

Метод apply() привязывает объект контекста для функции и СРАЗУ вызывает её. Отличается от call() только формой передачи второго параметра. Метод apply() ждёт «дополнительные параметры» (пробрасываемые) в виде массива.

 

Зачем нужно привязывать объект контекста вызова функции в JavaScript?

Необходимость привязки объекта контекста вызова функции подробно описана в публикации JavaScript | Что такое this?. Прочитайте её обязательно.

 

Информационные ссылки

Официальная страница стандарта ECMAScripthttps://tc39.es/ecma262/multipage/https://tc39.es/ecma262/

Раздел «Properties of the Function Prototype Object» — https://tc39.es/ecma262/#sec-properties-of-the-function-prototype-object