Перейти к содержимому

24. call, apply, bind

Иллюстрация к уроку Функции в JavaScript – это объекты первого класса, что означает, что они могут быть переданы как аргументы, возвращены из других функций и, самое главное, иметь контекст (this). Методы call, apply и bind позволяют нам управлять этим контекстом и, следовательно, выполнять функции в контексте другого объекта.

Контекст (this) в JavaScript – это значение, которое определяется тем, как вызывается функция. Он указывает на объект, в контексте которого выполняется код. call, apply и bind дают нам возможность явно указать, каким будет значение this при вызове функции.

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

const person = {
name: 'Иван',
sayHello: function(greeting) {
console.log(greeting + ', меня зовут ' + this.name);
}
};
const anotherPerson = {
name: 'Петр'
};
person.sayHello.call(anotherPerson, 'Привет'); // Вывод: Привет, меня зовут Петр

В этом примере мы вызываем функцию sayHello, принадлежащую объекту person, но в контексте объекта anotherPerson. Первый аргумент call – это контекст (this), а остальные аргументы – это аргументы, которые передаются в функцию sayHello.

Метод apply похож на call, но он принимает аргументы функции в виде массива.

const person = {
name: 'Иван',
sayHello: function(greeting, age) {
console.log(greeting + ', меня зовут ' + this.name + ', мне ' + age + ' лет.');
}
};
const anotherPerson = {
name: 'Петр'
};
person.sayHello.apply(anotherPerson, ['Привет', 30]); // Вывод: Привет, меня зовут Петр, мне 30 лет.

В этом примере аргументы sayHello передаются в виде массива ['Привет', 30] в apply.

Метод bind создает новую функцию, которая при вызове всегда будет иметь определенное значение this. В отличие от call и apply, bind не вызывает функцию сразу, а возвращает новую функцию с заданным контекстом.

const person = {
name: 'Иван',
sayHello: function(greeting) {
console.log(greeting + ', меня зовут ' + this.name);
}
};
const anotherPerson = {
name: 'Петр'
};
const sayHelloToPetr = person.sayHello.bind(anotherPerson);
sayHelloToPetr('Здравствуйте'); // Вывод: Здравствуйте, меня зовут Петр

Здесь bind создает новую функцию sayHelloToPetr, у которой this всегда будет указывать на anotherPerson.

В React bind часто используется для привязки контекста (this) к обработчикам событий. Например:

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this); // Привязываем контекст
}
handleClick() {
console.log('Кнопка нажата, контекст:', this);
}
render() {
return (
<button onClick={this.handleClick}>Нажми меня</button>
);
}
}

Без bind в конструкторе, this в handleClick будет undefined или указывать на другое значение (в зависимости от конфигурации React). bind гарантирует, что this будет указывать на экземпляр компонента MyComponent.

Также, call и apply могут быть полезны для заимствования методов у других объектов. Например, чтобы использовать slice для преобразования arguments (который не является настоящим массивом) в массив:

function myFunction() {
const args = Array.prototype.slice.call(arguments); // Преобразуем arguments в массив
console.log(args);
}
myFunction(1, 2, 3); // Вывод: [1, 2, 3]
  • call вызывает функцию с заданным контекстом и аргументами, переданными по отдельности.
  • apply вызывает функцию с заданным контекстом и аргументами, переданными в виде массива.
  • bind создает новую функцию с заданным контекстом, но не вызывает ее сразу.
  • Эти методы позволяют контролировать значение this внутри функции.
  • Часто используются для привязки контекста в обработчиках событий и для заимствования методов.