Javascript - 箭头函数在事件处理程序中的this指向问题?

17

我刚接触ES6,但是无法使它正常工作:

$(this)在点击事件中返回undefined?

dom.videoLinks.click((e) => {
            e.preventDefault();
            console.log($(this));
            var self = $(this),
                url = self.attr(configuration.attribute);

            eventHandlers.showVideo(url);

            // Deactivate any active video thumbs
            dom.videoLinks.filter('.video-selected').removeClass('video-selected');

            // Activate selected video thumb
            self.addClass('video-selected');
        });

然而,如果我将它更改为不是箭头函数(arrow function),像这样,它按预期工作吗?

dom.videoLinks.click(function(e) {
            e.preventDefault();
            console.log(this);
            console.log($(this));
            var self = e.this,
                url = self.attr(configuration.attribute);

            eventHandlers.showVideo(url);

            // Deactivate any active video thumbs
            dom.videoLinks.filter('.video-selected').removeClass('video-selected');

            // Activate selected video thumb
            self.addClass('video-selected');
        });

如果我在回调函数中使用 箭头函数,我该如何处理?

5个回答

40

当使用箭头函数作为回调函数时,不要使用this来获取处理程序绑定的元素,而是应该使用event.currentTarget
箭头函数内部的this由它被定义的位置决定,而不是它被使用的位置。因此,从现在开始,请记住event.currentTarget始终指向当前正在处理事件监听器的DOM元素。


.currentTarget vs .target

由于事件冒泡/捕获的原因,应该使用event.currentTarget而不是event.target

  • event.currentTarget是附加了事件监听器的元素。
  • event.target是触发事件的元素。

根据文档:

currentTarget的类型是EventTarget,只读属性,用于指示当前正在处理EventListenersEventTarget。这在捕获冒泡期间特别有用。

请在下面的代码示例中查看基本示例

var parent = document.getElementById('parent');
parent.addEventListener('click', function(e) {
  
  document.getElementById('msg').innerHTML = "this: " + this.id +
    "<br> currentTarget: " + e.currentTarget.id +
    "<br>target: " + e.target.id;
});

$('#parent').on('click', function(e) {

  $('#jQmsg').html("*jQuery<br>this: " + $(this).prop('id')
                   + "<br>currenTarget: " + $(e.currentTarget).prop('id') 
                   + "<br>target: " + $(e.target).prop('id'));
});

$('#parent').on('click', e => $('#arrmsg').html('*Arrow function <br> currentTarget: ' + e.currentTarget.id));
#parent {background-color:red; width:250px; height:220px;}
#child {background-color:yellow;height:120px;width:120px;margin:0 auto;}
#grand-child {background-color:blue;height:50px;width:50px;margin:0 auto;}
#msg, #jQmsg, #arrmsg {font-size:16px;font-weight:600;background-color:#eee;font-family:sans-serif;color:navy;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

  <div id="parent">Parent-(attached event handler)<br><br>
    <div id="child"> Child<br><br>
      <p id="grand-child">Grand Child</p>
    </div>
  </div>
 
  <div id="msg"></div><br>
  <div id="jQmsg"></div><br>
  <div id="arrmsg"></div>


10

你不会这样做。

改变this的值是使用箭头函数的主要目的。

如果你不想这样做,那么箭头函数就不是适合这个工作的工具。


4

即使在箭头函数内部,您也可以使用$(event.target)代替$(this)。箭头函数会保留它们定义所在范围的this。在您的情况下,thisundefined


2
箭头函数和this选择器?
箭头函数会保留来自外部上下文的this值。例如:
obj.method = function(){
    console.log(this);
    $('a').click(e=>{
            console.log(this);
    })
};
obj.method(); // logs obj
$('a').click(); // logs obj

如果我在回调函数中使用箭头函数,该怎么办?

你已经可以这样做了 - 要访问事件目标,你可以使用 $(e.target) 这样的方法,但要注意冒泡。因此,我建议使用普通函数作为回调。


-1
在箭头函数中,对this的处理与普通函数也不同。
简而言之,使用箭头函数时,没有绑定this
在普通函数中,this关键字代表调用该函数的对象,可以是窗口、文档、按钮或其他任何东西。
而在箭头函数中,this关键字始终表示定义箭头函数的对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接