为什么$(this)的工作方式不同取决于回调的创建方式

Why does $(this) work differently depending on how callback is created?

本文关键字:取决于 回调 方式 创建 方式不 工作 this 为什么      更新时间:2023-09-26

我试图显示一个表,并导致某些操作发生,如果用户单击表中的一个单元格。我的Javascript(使用jquery-3.1.1.min)看起来像这样:

    $(function() { 
      function tdHeader(key) {
          return '<td class="mytable-cell" data-key="' + key + '">';
      }
      function clickHandler() {
          alert("Key: " + $(this).data("key"));
      }
      function displayTable() {
          var tabHTML = '<table class="mmmtab">';
          tabHTML += '<tr><th>Data1</th><th>Data2</th><th>Data3</th></tr>';
          for (var i = 0; i < 3; i++) {
              tabHTML += '<tr>';
              for (var j = 0; j < 3; j++) {
                 key = i + "-" + j;
                 tabHTML += tdHeader(key) + ((i + 1) * (j + 1)) + '</td>';
              }
              tabHTML += '</tr>';
          }
          tabHTML += '</table>';
          $("#mytable").html(tabHTML);
          $(".mytable-cell").click(clickHandler);                 // Version 1
//        $(".mytable-cell").click(function() {clickHandler();}); // Version 2
      }
      displayTable();
    });

我发现的是,如果我使用版本1设置回调,那么如果我单击单元格,警报框将显示正确的键。但是,如果我使用版本2,则警告框显示"Key: undefined"。

发生了什么,为什么我使用哪个回调会有区别?

假设我需要版本2,因为我想传递一些本地数据给处理程序,我可以通过将$(this).data("key")作为参数传递给处理程序来解决我的问题。但我还是想知道它为什么会这样。

jQuery调用在事件所属元素的上下文中传递给click的回调。因此,对于$(".mytable-cell").click(clickHandler);, clickHandler在给定DOM元素的上下文中被调用。

对于$(".mytable-cell").click(function() {clickHandler();});,匿名函数是在DOM元素的上下文中调用的,而在undefined或全局对象的上下文中调用clickHandler

你需要写$(".mytable-cell").click(function() { return clickHandler.apply(this, arguments); } );如果你想要的行为是相同的

jQuery .on将自动更改事件回调的'this'。在版本1中,clickHandler中的'this'将是$(".mytable-cell")。但在版本2中,"this"是window。(因为你的事件回调调用clickHandler, clickHandler创建一个新的上下文)

请尝试:

$(".mytable-cell").click(function() {clickHandler.bind(this)();});