Как передать текущую область видимости в ссылку на функцию? - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть следующий код, который создает строку и добавляет событие к кнопке, которая показывает указанную строку:

function initEvents() {
  const message = processSomeString();
  myButton.addEventListener( () => {
    //Some other code
    alert(message);
  })
}

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

Я хотел бы удалить вложенную анонимную функцию для улучшения читабельности, но как мне присоединить переменную message к ссылочной функции?

Желательно современным способом, учитывая ES6 +

Function.prototype.bind () не был бы идеальным, поскольку мне нужна ссылка this, чтобы не измениться в моем реальном контексте.

function initEvents () {
  const message = processSomeString();
  myButton.addEventListener(myButtonClick);
}

function myButtonClick () {
  //Some other code
  alert(message??);
}

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Использование .bind:

function initEvents () {
  const message = 'any string' //processSomeString();
  
  // pass `myButton` as first argument of `.bind`
  // so that in your `myButtonClick()` you still have reference to `this`
  myButton.addEventListener('click', myButtonClick.bind(myButton, message));
}

function myButtonClick(message, e){
  console.log(`this: ${this}`);
  console.log(`message: ${message}`);
}

initEvents();
<button id="myButton">Button</button>

Обратите внимание, что в вашем коде эта строка: myButton.addEventListener(myButtonClick) не будет работать, потому что вам не хватает одного аргумента "eventType" для.addEventListener.

Изменить для соответствия вопроса:

Чтобы сохранить this ссылку на ключевое слово, просто передайте this в качестве первого аргумента:

function initEvents () {
  const message = 'any string' //processSomeString();

  // For JS beginners, just read the documentation link above for explanation
  myButton.addEventListener('click', myButtonClick.bind(this, message));
}

function myButtonClick(message, e){
  console.log(`this: ${this}`);
  console.log(`message: ${message}`);
}

initEvents();
<button id="myButton">Button</button>
0 голосов
/ 11 декабря 2018

Вы не можете передать область , вам нужно будет передать аргументы :

function myButtonClick(message) {
  //Some other code
  alert(message);
}

function initEvents() {
  const message = processSomeString();

  myButton.addEventListener(() => myButtonClick.call(this, message));
  // or:
  myButton.addEventListener(myButtonClick.bind(this, message));
}

Хотя обратите внимание, что я нахожу странным сохранение this здесь.Это имеет смысл, только если обе функции являются методами для одного и того же объекта, и в этом случае .bind(this) является общей идиомой.Если они не связаны между собой, передача контекста this таким образом… неожиданна.

...