D3.js事件侦听器无法访问“”;这个“;当使用ES6箭头功能时

D3.js event listeners cannot access "this" when ES6 arrow functions are used

本文关键字:ES6 功能 这个 侦听器 访问 js D3 事件      更新时间:2023-09-26

我正在尝试使用带有箭头函数的D3.js事件侦听器,但它似乎不起作用。

绑定到未定义

如何使用ES6箭头函数访问this

ES5:

svg.selectAll('circle')
  .data(data)
  .enter()
  .append('circle')
  .attr('r', '10')
  .attr('cx', (d) => x(d.day))
  .attr('cy', (d) => y(d.amount))
  .on('mouseenter', function (d) {
    console.log(this); // output '<circle r="10" cx="10" cy="1"/>'
  });

ES6(使用箭头功能):

svg.selectAll('circle')
  .data(data)
  .enter()
  .append('circle')
  .attr('r', '10')
  .attr('cx', (d) => x(d.day))
  .attr('cy', (d) => y(d.amount))
  .on('mouseenter', (d) => {
    console.log(this); // output: 'undefined'
  });

这是预期行为。(以下是我解释这种行为的拙劣尝试。你最好读一下)

执行箭头函数的上下文(this)将是定义它们的上下文(无论this在函数之外是什么)

D3可能会将事件侦听器的上下文设置为发出事件的对象(如ES5示例中所示)。

但是,通过使用箭头函数,您将强制上下文绑定到定义函数的上下文。在您的情况下,此上下文是未定义的/window,因为您的代码不包含在另一个函数中。

如果我将您的ES6示例转换回ES5,也许会更好地解释):

var self = this;    
svg.selectAll('circle')
      .data(data)
      .enter()
      .append('circle')
      .attr('r', '10')
      .attr('cx', (d) => x(d.day))
      .attr('cy', (d) => y(d.amount))
      .on('mouseenter', (d) => {
        console.log(self); // output: 'undefined'
      });

我对解决你的问题的建议很简单。使用常规的function作为您的事件订阅者(对您的两个"属性"订阅者使用箭头函数也没有任何好处)。

svg.selectAll('circle')
  .data(data)
  .enter()
  .append('circle')
  .attr('r', '10')
  .attr('cx', (d) => x(d.day))
  .attr('cy', (d) => y(d.amount))
  .on('mouseenter', function(d) {
    console.log(this); // output '<circle r="10" cx="10" cy="1"/>'
  });