Связать с addEventListener - PullRequest
       37

Связать с addEventListener

0 голосов
/ 02 ноября 2019

При использовании bind() в Слушателе событий в JavaScript я больше не могу получить элемент с «this».

Вот мой код:

function callback(){

     console.log(this.someVar);
     // Works fine

     console.log(this);
     // No longer refers to the element, outputs "Object"

}

callback = callback.bind({someVar: 1234});

element.addEventListener('click', callback);

Любая идея о том, какчтобы исправить это?

Ответы [ 3 ]

1 голос
/ 03 ноября 2019

Если вы хотите передать одну переменную, но сохранить контекст this, вы можете использовать карри или частичное применение:

Карри

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

function callback(num) {
  return function() {
    console.log(num);
    console.log(this.id);
  }
}

var number = 1;

document.getElementById("hello").addEventListener("click", callback(number));

//change the variable
number = 2;
document.getElementById("world").addEventListener("click", callback(number));

//change the variable again
number = 3;
<button id="hello">Hello</button>
<button id="world">World</button>

Частичное приложение

Та же идея, но вместо того, чтобы ваш обратный вызов возвращал новую функцию, она просто потребуетодин аргумент и работает нормально, вам нужна другая функция, которая будет выполнять частичное применение:

function callback(num) {
  console.log(num);
  console.log(this.id);
}

var number = 1;

document.getElementById("hello").addEventListener("click", partial(callback, number));

//change the variable
number = 2;
document.getElementById("world").addEventListener("click", partial(callback, number));

//change the variable again
number = 3;


function partial(fn, arg) {
  return function() {
    return fn.call(this, arg);
  }
}
<button id="hello">Hello</button>
<button id="world">World</button>

Функция частичного применения может быть обобщена для обработки любой суммы или аргументов

В ES6:

function partial(fn, ...args) {
  return function(...otherArgs) {
    return fn.apply(this, [...args, ...otherArgs]);
  }
}

InES5:

function partial(fn) {
  var args = [].prototype.slice.call(arguments, 1);
  return function() {
    var otherArgs = [].[].prototype.slice.call(arguments);
    return fn.apply(this, args.concat(otherArgs));
  }
}
0 голосов
/ 03 ноября 2019

Метод bind() создает новую функцию, для которой при вызове ее ключевое слово this устанавливается на указанное значение.

Таким образом, при вызове функции, подобной

callback = callback.bind({someVar:1234})

this внутри функции обратного вызова будет объектом {someVar:1234}

Для доступа к someVar в функции обратного вызова необходимо использовать this.someVar.

Надеюсь, это поможет.

Если вам все еще неясно, обратитесь к этой статье https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind

0 голосов
/ 03 ноября 2019

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

function f() {return this;}
f = f.bind({a:1});
f(); // => {a:1}
f = f.bind({a:2}); // this is what addEventListener actually do as if it bind this to even
f(); // {a:1}

addEventListener не может связать это снова.

...