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
相关产品推荐
相关产品推荐

