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

ThreeJS JSONLoader结合OOP:加载回调中this.scene未定义问题求助

解决this.scene在Three.js回调中为undefined的问题

嘿,我完全懂你遇到的这个困扰——这绝对是JavaScript里this绑定的经典陷阱,尤其是在异步回调场景里!咱们来一步步拆解问题,然后给出解决方案。

问题根源

在你的loadModel方法里,你用了传统的function()来定义loader.load的回调函数:

this.loader.load(model, function(geometry, materials){
  // ... 这里的this不是App3D实例!
});

JavaScript里,传统函数的this是动态绑定的:当这个回调被Three.js的loader调用时,this的指向已经不再是你的App3D实例了,而是回调函数自身的执行上下文,所以this.scene自然就变成了undefined。

三种解决方案

下面是几种常见的修复方式,你可以选自己习惯的一种:

1. 使用箭头函数(最简洁的现代方案)

箭头函数不会绑定自己的this,它会继承外层作用域(也就是loadModel方法)的this,也就是你的App3D实例:

loadModel(model){
  this.loader.load(model, (geometry, materials) => {
    let material = new THREE.MultiMaterial( materials );
    let mesh = new THREE.Mesh( geometry, material );
    this.scene.add(mesh); // 这里的this现在指向App3D实例
    this.objects.push(mesh);
  });
}

2. 提前保存this到变量

在回调外把当前实例的this存到一个变量(比如self或者that),然后在回调里用这个变量访问实例属性:

loadModel(model){
  const self = this; // 保存App3D实例的引用
  this.loader.load(model, function(geometry, materials){
    let material = new THREE.MultiMaterial( materials );
    let mesh = new THREE.Mesh( geometry, material );
    self.scene.add(mesh); // 用self代替this访问实例
    self.objects.push(mesh);
  });
}

3. 用bind()绑定this

通过bind()方法手动把回调函数的this绑定到App3D实例:

loadModel(model){
  this.loader.load(model, function(geometry, materials){
    let material = new THREE.MultiMaterial( materials );
    let mesh = new THREE.Mesh( geometry, material );
    this.scene.add(mesh);
    this.objects.push(mesh);
  }.bind(this)); // 绑定this到App3D实例
}

额外小提示

顺便提一句:Three.js的THREE.MultiMaterial已经被官方废弃啦!现在你可以直接把材质数组传给Mesh的第二个参数,写法更简洁:

let mesh = new THREE.Mesh(geometry, materials); // 直接用materials数组

希望这些方法能帮你解决问题,继续享受学习OOP、JS和Three.js的过程吧!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:27:25