我正在尝试使用带有箭头函数的 D3.js 事件监听器,但它似乎不起作用。
this 绑定(bind)到 undefined。
如何使用 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'
});
这是预期的行为。 (以下是我试图解释这种行为的糟糕尝试。你可能会过得更好 reading this )
执行箭头函数的上下文 (this
) 将是定义它们的上下文(无论 this
在函数之外)
D3 可能会将事件监听器的上下文设置为发出事件的对象(如 ES5 示例中所示)。
但是,通过使用箭头函数,您强制将上下文绑定(bind)到您定义函数的上下文。在您的情况下,此上下文未定义/窗口,因为您的代码未包含在另一个函数中。
如果我将您的 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
作为您的事件订阅者(对您的两个“attr”订阅者使用箭头函数也没有任何好处)。
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"/>'
});