简体   繁体   English

事件监听器绑定的函数如何继承`this`对象

[英]How do functions bound by event listeners inherit `this` object

Pure Javascript only please. 请只使用纯Javascript。 - also I'm pretty noob, so sorry if my question is a little convoluted. -我也很菜鸟,很抱歉,如果我的问题有点混乱。

I'm operating on an htmlCollection var puzzleAreaContents - which contains 16 <div> tags 我正在htmlCollection var puzzleAreaContents -包含16个<div>标签

next we go inside a loop, cycling through the elements, adding a click event listener. 接下来,我们进入一个循环,循环遍历元素,添加一个click事件侦听器。

puzzleAreaContents[movables[i]].addEventListener("click", shiftPuzzlePiece);

when I click on the element, I have access to this inside the shiftPuzzlePiece function, "this" being the the <div> tag I just clicked on. 当我单击该元素时,可以在shiftPuzzlePiece函数中访问this元素,“ this”是我刚刚单击的<div>标记。

I have two questions 我有两个问题

  1. how / why does shiftPuzzlePiece function have access to this , the clicked dom element ? shiftPuzzlePiece函数如何/为什么可以访问this ,单击的dom元素?
  2. how can I pass any arbitrary element to shiftPuzzlePiece without breaking it's current usability? 如何在不破坏当前可用性的情况下将任意元素传递给shiftPuzzlePiece -- How can I define this when I'm passing the function an object, so that it behaves the same or similarly to when it is called via the click event listener? -如何界定this时候我传递函数的对象,所以它的行为相同或类似的,当它通过点击事件侦听器叫?

that is to say that it is not currently set up to receive arguments 也就是说,它当前未设置为接收参数

ex: shiftPuzzlePiece(some_arg) 例如: shiftPuzzlePiece(some_arg)

  1. The event handler creates a new Execution Context ECMA which binds this to the element clicked 事件处理程序将创建一个新的执行上下文ECMA ,它将其绑定到单击的元素
  2. You can use your own binding in order to replace this with call MDN . 您可以使用自己的结合,以代替this呼叫MDN

For example, 例如,

shiftPuzzlePiece.call(puzzleAreaContents[movables[i]]);

Usually you call a function as a statement/expression: 通常,您将函数称为语句/表达式:

var ret = shiftPuzzlePiece(arg0);

There are also Function.prototype.call and .apply , with which you can provide the this context: 还有Function.prototype.call.apply ,您可以使用它们提供this上下文:

var ret = shiftPuzzlePiece.call(that, arg0);
var ret = shiftPuzzlePiece.apply(that, [ arg0 ]);

Now that becomes this inside the function. 现在that变成this函数内。


Example

var piece = { };

puzzleAreaContents[movables[i]].addEventListener("click", function () {

    shiftPuzzlePiece.call(piece, this /* element */);

});

function shiftPuzzlePiece(element) {

   // this === piece
   // element === the clicked puzzleAreaContents

}

You can bind any value to be the this object by using bind . 您可以将任何值绑定是this使用对象bind For example: 例如:

shiftPuzzlePiece.bind({x:23});

Will ensure that the this object will have this.x equal to 23 . 将确保this对象的this.x等于23

You can also give pass in other parameters as well, but they would have to be in order. 您也可以传递其他参数,但是它们必须是有序的。 Bind returns a function. 绑定返回一个函数。

More info about bind here . 有关在此处绑定的更多信息。

The call and apply functions work similarly, but they do not return a new function but instead call the function. callapply函数的工作原理类似,但是它们不返回新函数而是调用该函数。

Another way not mentioned here is using a closure which actually is faster than apply() , call() and bind() 这里没有提到的另一种方法是使用一个closure ,它实际上比apply()call()bind()更快

(function f(){
  this.a = 0;
  var self = this;
  var e = document.getElementById('list').children, i;
  for (i = 0; i < e.length; i++) {
    (function(i){
      e[i].onclick = function(){
        _f(this, i);
      };
    })(i);
  }
})();

Or, it may be written like this as well 或者,也可以这样写

(function f(){
  this.a = 0;
  var self = this;
  var e = document.getElementById('list').children, i;
  for (i = 0; i < e.length; i++) {
    e[i].onclick = (function(i){
      return function() {
        _f(this, i);
      };
    })(i);
  }
})();

And finally, the _f function in this case 最后,在这种情况下, _f函数

function _f(y, z){
  console.log(this.a + " / " + y.innerHTML + " / " + z);
}

HTML HTML

<ul id="list">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

Output: 输出:

0 / 1 / 0
0 / 2 / 1
0 / 3 / 2
0 / 4 / 3
0 / 5 / 4

Working jsBin | 工作jsBin | Banchmark Banchmark

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何删除受外部脚本约束的事件侦听器 - How to remove event listeners bound by external script 这在Meteor的事件处理功能中:这如何绑定到模型对象? - this in event handling functions of Meteor: How does this get bound to model object? 如何添加和删除作为箭头函数的事件侦听器 - How to add and remove event listeners that are arrow functions 如何理解事件监听器在窗口对象上的执行? - How to understand the event listeners execution on window object? 如何在Java或JavaScript中为事件侦听器提供对象池 - How to Object pool for event Listeners in Java or JavaScript 如何防止单个对象上的多个事件侦听器? - How to prevent multiple event listeners on single object? 事件侦听器是否像返回的内部函数一样工作? - Do event listeners work like returned inner functions? 如何执行绑定到事件的侦听器并排除绑定到执行中的不同事件的其余侦听器? - How to execute a listener bound to an event and exclude the remaining listeners bound to different events from execution? 我如何定义此对象以便将事件侦听器添加到表单中? 不确定该怎么做 - how do i define this object in order to add event listeners to my form? unsure of what to do 我如何继承javascript函数? - How do I inherit javascript functions ?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM