简体   繁体   中英

Assign variable from inner function to outer scope

I'm trying to make this code works, but I'm on the rocks with the functions scopes.

This is my code so far:

var Canoe = function () {
    this.mesh = new THREE.Object3D();
    var loader = new THREE.JSONLoader();
    loader.load( 'models/canoe.json', function ( geometry, materials ) {
        var canoeMesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ));
        canoeMesh.castShadow = true;
        canoeMesh.receiveShadow = true;
        this.mesh.add(canoeMesh);
    });

}

And this is the error I'm getting:

Cannot read property 'add' of undefined

How can I assign the mesh I created in the inner function to the outer variable?

One solution is to put mesh in a variable defined in the function:

var Canoe = function () {
var mesh = new THREE.Object3D();
this.mesh = mesh;
var loader = new THREE.JSONLoader();
loader.load( 'models/canoe.json', function ( geometry, materials ) {
    var canoeMesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ));
    canoeMesh.castShadow = true;
    canoeMesh.receiveShadow = true;
    mesh.add(canoeMesh);
});

Someone could write a book on how this works in javascript. It's often not what you expect.

Before loader.load() add

var that = this;

In your load function put

that.mesh.add(canoeMesh);

Problem is that "this" inside loader.load() points to somewhere else than outside of the function.

I think you've got a couple options. One, is to assign this to another variable, like so:

var self = this;
var Canoe = function () {
    self.mesh = new THREE.Object3D();
    var loader = new THREE.JSONLoader();
    loader.load( 'models/canoe.json', function ( geometry, materials ) {
        var canoeMesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ));
        canoeMesh.castShadow = true;
        canoeMesh.receiveShadow = true;
        self.mesh.add(canoeMesh);
    });
}

Another option, if you have a transpiler, would be to use an arrow function, which retains lexical this :

var Canoe = () => {
    this.mesh = new THREE.Object3D();
    var loader = new THREE.JSONLoader();
    loader.load( 'models/canoe.json', function ( geometry, materials ) {
        var canoeMesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ));
        canoeMesh.castShadow = true;
        canoeMesh.receiveShadow = true;
        this.mesh.add(canoeMesh);
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM