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

时间:2014-08-07 19:11:53

标签: javascript

纯粹的Javascript请。 - 我也很漂亮,如果我的问题有点令人费解,那就很抱歉。

我正在使用htmlCollection var puzzleAreaContents - 其中包含16个<div>标记

接下来我们进入一个循环,循环遍历元素,添加一个click事件监听器。

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

当我点击该元素时,我可以访问this函数中的shiftPuzzlePiece,“此”是我刚刚点击的<div>标记。

我有两个问题

  1. shiftPuzzlePiece函数如何/为何可以访问this,点击的dom元素?
  2. 如何在不破坏当前可用性的情况下将任意元素传递给shiftPuzzlePiece? - 当我将函数传递给对象时,如何定义this,使其行为与通过click事件监听器调用它时的行为相同或类似?
  3. 也就是说它目前没有设置为接收参数

    ex:shiftPuzzlePiece(some_arg)

4 个答案:

答案 0 :(得分:1)

  1. 事件处理程序会创建一个新的 Execution ContextECMA ,将其与单击的元素绑定
  2. 您可以使用自己的绑定来将this替换为 callMDN
  3. 例如,

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

答案 1 :(得分:0)

通常将函数作为语句/表达式调用:

var ret = shiftPuzzlePiece(arg0);

还有Function.prototype.call.apply,您可以使用this上下文提供:

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

现在that在函数内变为this


实施例

var piece = { };

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

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

});

function shiftPuzzlePiece(element) {

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

}

答案 2 :(得分:0)

您可以使用this将任何值绑定为bind对象。例如:

shiftPuzzlePiece.bind({x:23});

确保this对象的this.x等于23

您也可以传递其他参数,但它们必须按顺序排列。绑定返回一个函数。

有关bind here的更多信息。

callapply函数的工作方式类似,但它们不会返回新函数,而是调用函数。

答案 3 :(得分:0)

此处未提及的另一种方法是使用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);
  }
})();

或者,也可以像这样写出

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

最后,本例中的_f函数

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

HTML

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

输出:

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

工作jsBin | Banchmark