Каков принцип работы метода bind в JavaScript?

Как работает метод `bind()` и почему при замене оригинальной функции в объекте на другую все еще вызывается исходная функция?
  • 25 марта 2024 г. 9:29
Ответы на вопрос 2
Метод `bind()` в JavaScript используется для создания новой функции, у которой указан контекст выполнения (this) и набор параметров заданы заранее. 

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

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

Для того чтобы перезаписать оригинальную функцию в объекте новой функцией с привязанным контекстом, можно просто переприсвоить свойство объекта на результат вызова `bind()`. 

Пример:

```javascript
const obj = {
  name: 'Alice',
  sayHello: function() {
    console.log('Hello, ' + this.name);
  }
};

const newFunc = obj.sayHello.bind({ name: 'Bob' });
obj.sayHello = newFunc; // перезаписываем оригинальную функцию

obj.sayHello(); // выведет: "Hello, Bob"
```
bind кэширует текущее значение своего this в момент своего вызова, т.е. он привязывает именно функцию, а не объект, в котором находится функция. Иначе нельзя было бы вызывать bind на просто функции по типу foo.bind(abc) . В мануале, кстати, описано что именно она кэширует - там полный список есть: https://developer.mozilla.org/ru/docs/Web/JavaScri... 

Упрощенный пример реализации bind для понимания механизма:
function binder(that) { 
    let targetFunction = this; // кэш целевой функции
    return function() { targetFunction.call(that) } // В возвращаемой функции используем кэш
}

let user = {
  name: "Tom",
  intro() {
    console.log("I am " + this.name);
  }
}

user.intro.binder = binder 
let f = user.intro.binder(user);

setTimeout(f, 1000);

user.name = "Sid";
user.intro = function() {
  console.log("Вообще другая функция. name: " + this.name);
}
Похожие вопросы