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

Я понимаю, зачем нужен метод bind и чисто механически вижу эффект. Но не понимаю механику его работы и вот почему:
У Ильи кантора написано следующее:
Результатом вызова func.bind(context) является особый «экзотический объект» (термин взят из спецификации), который вызывается как функция и прозрачно передаёт вызов в func, при этом устанавливая this=context.

У Флэнагана вот это:
When you invoke the bind() method on a function f and pass an
object o, the method returns a new function. Invoking the new function
(as a function) invokes the original function f as a method of o.

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

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

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

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

setTimeout(f, 1000);

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


Получаем в результате фразу "I am Sid", т.е. новые данные увиделись, а функция осталась старая. Выглядит так как будто при бинде именно создается копия исходной функции и вызывается именно она, безо всяких переадресаций.
  • Вопрос задан
  • 1202 просмотра
Решения вопроса 1
VoidVolker
@VoidVolker Куратор тега JavaScript
Dark side eye. А у нас печеньки! А у вас?
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);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы