当使用ES6箭头函数时,D3.js事件侦听器无法访问“this”

时间:2015-12-04 10:28:57

标签: javascript d3.js ecmascript-6

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

绑定到未定义

如何使用ES6箭头功能访问

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

1 个答案:

答案 0 :(得分:4)

这是预期的行为。 (以下是我在解释这种行为方面的不良尝试。你可能会更好地离开reading this

执行箭头函数的上下文(this)将是定义它们的上下文(函数外this

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

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

如果我将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作为您的活动订阅者(对于您的两位&#39;订阅者,使用箭头功能也没有任何好处。)

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"/>'

  });