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

时间:2018-12-11 13:09:38

标签: javascript optimization ecmascript-6 readability

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

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 :(得分:2)

使用.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)不起作用,因为您缺少.addEventListener的一个"eventType" argument

修改以适合问题:

要保留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>

答案 1 :(得分:1)

您不能通过作用域,需要传递参数

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