Вернуться к уроку

Повторный bind

важность: 5

Ответ: "Вася".

function f() {
  alert(this.name);
}

f = f.bind( {name: "Вася"} ).bind( {name: "Петя"} );

f(); // Вася

Первый вызов f.bind(..Вася..) возвращает «обёртку», которая устанавливает контекст для f и передаёт вызов f.

Следующий вызов bind будет устанавливать контекст уже для этой обёртки. Это ни на что не повлияет.

Чтобы это проще понять, используем наш собственный вариант bind вместо встроенного:

function bind(func, context) {
  return function() {
    return func.apply(context, arguments);
  };
}

Код станет таким:

function f() {
  alert(this.name);
}

f = bind(f, {name: "Вася"} ); // (1)
f = bind(f, {name: "Петя"} ); // (2)

f(); // Вася

Здесь видно, что первый вызов bind, в строке (1), возвращает обёртку вокруг f, которая выглядит так (выделена):

function bind(func, context) {
  return function() {
    // здесь this не используется
    return func.apply(context, arguments);
  };
}

В этой обёртке нигде не используется this, контекст context берётся из замыкания. Посмотрите на код, там нигде нет this.

Поэтому следующий bind в строке (2), который выполняется уже над обёрткой и фиксирует в ней this, ни на что не влияет. Какая разница, что будет в качестве this в функции, которая этот this не использует? Контекст context, как видно в коде выше, она получает через замыкание из аргументов первого bind.

Что выведет этот код?

function f() {
  alert(this.name);
}

f = f.bind( {name: "Вася"} ).bind( {name: "Петя" } );

f();