JavaScript: this, call, bind, apply — просто и понятно

В JavaScript контекст this — важная, но часто непонятная концепция. Он определяет текущий объект, в контексте которого выполняется функция. Рассмотрим работу this и управление им с помощью методов call, bind и apply.

Глобальный контекст

Функция hello выводит сообщение в консоль и значение this:

function hello() {
  console.log("Hello", this);
}

Вызов hello() без привязки к объекту делает this равным глобальному объекту window:

hello(); // Выведет "Hello" и объект window

window — глобальный объект браузера, содержащий встроенные функции (например, alert).

Контекст this в объектах

Объект person:

const person = {
  name: "Владилен",
  age: 25,
  sayHello: hello
};

Вызов person.sayHello() меняет контекст this:

person.sayHello(); // Выведет "Hello" и объект person

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

Метод bind

Вызов функции hello в контексте window внутри объекта person:

person.sayHelloWindow = hello.bind(window);
person.sayHelloWindow(); // Выведет "Hello" и объект window

bind создаёт новую функцию с this, привязанным к указанному объекту (window).

Методы call и apply

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

person.sayHelloDocument = hello.bind(document);
person.sayHelloDocument(); // Выведет "Hello" и объект document

hello.call(document); // Выведет "Hello" и объект document
hello.apply(document, []); // Выведет "Hello" и объект document

Функция logInfo

Функция logInfo выводит информацию об объекте:

function logInfo() {
  console.log(`Name is ${this.name}`);
  console.log(`Age is ${this.age}`);
}

person.logInfo() выведет информацию о person:

person.logInfo(); // Выведет информацию о person

Для вывода информации о другом объекте (lena) используем bind, call или apply:

const lena = { name: "Елена", age: 23 };
person.logInfo.call(lena); // Выведет информацию о lena

Расширение прототипа

Пример умножения элементов массива на число. Функция multiplyBy:

function multiplyBy(arr, n) {
  return arr.map(item => item * n);
}

Более элегантный способ — расширение прототипа массива:

Array.prototype.multiplyBy = function(n) {
  return this.map(item => item * n);
};

Теперь каждый массив имеет метод multiplyBy:

const arr = [1, 2, 3, 4, 5];
const newArr = arr.multiplyBy(2); // newArr будет [2, 4, 6, 8, 10]

this внутри multiplyBy указывает на массив.

Понимание контекста this и управление им с помощью bind, call и apply — важные навыки для JavaScript. Это позволяет создавать гибкий, читаемый и эффективный код, особенно при работе с объектами и прототипами.

Что будем искать? Например,программа