如何将当前范围传递给函数引用?

How to pass current scope to a function reference?

我有以下代码构造一个字符串并向显示所述字符串的按钮添加一个事件:

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??);
}

您不能传递 scope,您需要传递 arguments:

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 上下文是……意外的。

使用.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" argument 用于 .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>