You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数内更新类属性问题:点击事件中this指向不符预期

解决D3点击事件中类实例this指向问题

这个问题我太熟了——在D3的事件处理函数里,用传统function()定义的回调会把this绑定到被点击的DOM元素(也就是你代码里的<rect>元素),而不是你的Chart类实例,所以你直接赋值this.bar = d根本找不到类里的bar属性。给你三个实用的解决办法:

1. 用ES6箭头函数(最推荐)

箭头函数不会创建自己的this上下文,它会继承外层作用域的this,也就是你的Chart类实例。这样你就能直接在回调里访问类的bar属性了:

export class Chart { 
  constructor() { 
    this.bar; 
  } 
  showChart() { 
    // ... 你的其他代码
    let group = svg.selectAll('g').data(data).enter().append('g'); 
    group.append('rect') 
      .on('click', (d) => { 
        // 这里的this就是Chart类的实例了!
        this.bar = d; 
      }); 
  } 
}

⚠️ 注意:如果之后你需要访问被点击的DOM元素,箭头函数里不能用this,得用d3.event.currentTarget来获取。

2. 提前保存类实例的this到变量

如果你的环境还不支持ES6箭头函数,可以在showChart方法开头先把类实例的this存到一个变量(比如self或者that),然后在回调里用这个变量访问类属性:

export class Chart { 
  constructor() { 
    this.bar; 
  } 
  showChart() { 
    // 先把类实例的this存下来
    const self = this;
    // ... 你的其他代码
    let group = svg.selectAll('g').data(data).enter().append('g'); 
    group.append('rect') 
      .on('click', function(d) { 
        // 用self代替this,指向Chart类实例
        self.bar = d; 
        // 这里的this还是被点击的rect元素,需要的话可以正常用
      }); 
  } 
}

3. 用bind()绑定this

你也可以通过bind()方法把回调函数的this强制绑定到类实例上:

export class Chart { 
  constructor() { 
    this.bar; 
  } 
  showChart() { 
    // ... 你的其他代码
    let group = svg.selectAll('g').data(data).enter().append('g'); 
    group.append('rect') 
      .on('click', function(d) { 
        this.bar = d; 
      }.bind(this)); // 把this绑定到Chart类实例
  } 
}

这种方法和箭头函数的效果类似,但需要手动调用bind,代码稍微啰嗦一点。

内容的提问来源于stack exchange,提问作者isar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:31:57