【问题标题】:Bind with addEventListener与 addEventListener 绑定
【发布时间】:2019-11-02 20:56:12
【问题描述】:

在 JavaScript 中的事件侦听器上使用 bind() 时,我无法再获取带有“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);

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 这就是bind 所做的——它永久设置this 上下文。如果你不想要这种行为,那么也许你不应该使用bind
  • 你得到了什么输出?
  • @VLAZ 我可以用什么替代?
  • @KaleshKaladharan "对象"
  • @VLAZ 我想在事件中将一个变量传递给函数,但这个变量是不断变化的。当事件触发时,我希望函数从创建 EventListener 时输出变量的值。

标签: javascript events dom-events addeventlistener


【解决方案1】:

如果您想传递一个变量但保留this 上下文,那么您可以使用柯里化或部分应用:

Curry

您的函数必须接收一个值并返回另一个函数。这样您可以执行以下操作:

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>

Partial application

同样的想法,但不是让你的回调返回一个新函数,它只需要一个参数并正常工作,你需要另一个函数来执行部分应用:

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

在 ES5 中:

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

【讨论】:

    【解决方案2】:

    你仍然可以使用 event.target 并且可以访问被点击的元素。

    function callback(event){
    
     console.log(this.someVar);
     // Works fine
    
     console.log(event.target);
     // No longer refers to the element, outputs "Object"
    
    }
    
    callback = callback.bind({someVar: 1234});
    
    element.addEventListener('click', callback);
    

    【讨论】:

      【解决方案3】:

      您只能调用一次 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 无法再次绑定。

      【讨论】:

      • 您可以多次拨打bind。即使你在绑定函数上调用它,你也可以执行部分​​应用。
      • 我的意思是在callback = callback.bind({someVar: 1234});的上下文中
      【解决方案4】:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-28
        • 2022-10-13
        • 2016-04-26
        • 2022-07-16
        • 1970-01-01
        • 2019-07-01
        • 1970-01-01
        • 2012-02-18
        相关资源
        最近更新 更多