Понимание bind() в JavaScript

Согласно MDN: метод привязки

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

function f() {
  return this.a;
}

var g = f.bind({a: 'azerty'});
console.log(g()); // azerty

var h = g.bind({a: 'yoo'}); // bind only works once!
console.log(h()); // azerty

var o = {a: 37, f: f, g: g, h: h};
console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty

Но когда я пробую код ниже:

var module = {
  x: 42,
  getX: function() {
    return this.x;
  }
}
    
var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined
    
var boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // expected output: 42
 
module.x = 43;
boundGetY = boundGetX.bind(module);
console.log(boundGetY()); // shouldn't this be 42??

Ожидаемый результат:

undefined
42
42

Фактический результат:

undefined
42
43

Может кто-нибудь объяснить мне это?


person Souvik Ghosh    schedule 18.12.2018    source источник
comment
После запуска строки module.x = 43; module.x будет 43, а не 42, поэтому вы видите 43? После этого в памяти нет 42, почему вы ожидаете увидеть 42?   -  person CertainPerformance    schedule 18.12.2018
comment
@CertainPerformance Потому что они говорят, что bind() является постоянным и работает только один раз с переданным ему первым параметром?   -  person Souvik Ghosh    schedule 18.12.2018
comment
Нет, это работает не только один раз, вы можете продолжать вызывать связанную функцию столько раз, сколько захотите, и .bind не будет глубоко клонировать новую this или что-то в этом роде.   -  person CertainPerformance    schedule 18.12.2018


Ответы (3)


здесь модуль является константой, а module.x — нет. по этой причине вы можете изменить значение module.x, но не можете изменить модуль.

поэтому вы меняете значение модуля, а не сам модуль.

person Siddharth Bhandari    schedule 18.12.2018

Я не понимаю, что вас смущает - похоже, это работает так, как описано.

  1. unboundGetX — это ссылка на вашу функцию.
  2. Вы меняете значение module.x на 43
  3. Вы создаете новый метод boundGetY, вызывая unboundGetX.bind(module), т. е. this, на который ссылаетсяboundGetY, это module.
  4. Вы называете boundGetY() - это относится к this.x, что является значением module.x, 43.
person dwjohnston    schedule 18.12.2018

Когда вы меняете значение одного и того же объекта, вы не привязываете другой объект, поэтому значение изменяется.

  var module = {
      x: 42,
      getX: function() {
        return this.x;
      }
    }
    
    var unboundGetX = module.getX;
    console.log(unboundGetX()); // The function gets invoked at the global scope
    // expected output: undefined
    
    var boundGetX = unboundGetX.bind(module);
    console.log(boundGetX());  // expected output: 42
   
    var module2 = {
      x: 43,
      getX: function() {
        return this.x;
      }
    }
    boundGetY = boundGetX.bind(module);
    console.log(boundGetY());  

person siddharth darji    schedule 18.12.2018