0

I am a beginner in javascript, and I don't know why my variable is undefine.

Here is my code:

function createBlockMap(data) {
//console.log(data.X + " " + data.Y + " " + data.food);

    var makeOverOut = function (mesh) {
        mesh.actionManager = new BABYLON.ActionManager(scene);
        mesh.actionManager.registerAction(new BABYLON.SetValueAction(BABYLON.ActionManager.OnPointerOverTrigger, mesh.material, "diffuseTexture", mesh.material.diffuseTexture = new BABYLON.Texture("../assets/GrassLight.jpg", scene)));
        mesh.actionManager.registerAction(new BABYLON.SetValueAction(BABYLON.ActionManager.OnPointerOutTrigger, mesh.material, "diffuseTexture", mesh.material.diffuseTexture = new BABYLON.Texture("../assets/Grass.jpg", scene)));
        mesh.actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPointerOutTrigger, mesh, "scaling", new BABYLON.Vector3(1, 1, 1), 150));
        mesh.actionManager.registerAction(new BABYLON.InterpolateValueAction(BABYLON.ActionManager.OnPointerOverTrigger, mesh, "scaling", new BABYLON.Vector3(1.1, 1.1, 1.1), 150));
        mesh.actionManager.registerAction(new BABYLON.SetValueAction(BABYLON.ActionManager.OnPickTrigger, button2Rect, "levelVisible", true))
        .then(new BABYLON.SetValueAction(BABYLON.ActionManager.OnPickTrigger, button2Rect, "levelVisible", false));
    }

    var blockInfo = function (data) {
        box = new BABYLON.Mesh.CreateBox("crate", 1, scene);
        box.material = new BABYLON.StandardMaterial("Mat", scene);
        box.material.diffuseTexture = new BABYLON.Texture("../assets/Grass.jpg", scene);
        box.position.z = data.Y;
        box.position.x = data.X;
        box.position.y = 3;
        ownfood = data.food;
        console.log(this.ownfood);
        console.log(data.food);
        Linemate = data.Linemate;
        Deraumere = data.Deraumere;
        Sibur = data.Sibur;
        Mendiane = data.Mendiane;
        Phiras = data.Phiras;
        Thystame = data.Thystame;
        makeOverOut(box);
    }

    var button2Rect = new BABYLON.Rectangle2D(
        {   parent: canvas, id: "buttonClickRes", x: 250, y: 250, width: 100, height: 40, fill: "#4040C0FF",
        roundRadius: 10, isVisible: false,
        children:
        [
            new BABYLON.Text2D("Food: " + blockInfo.ownfood, { id: "clickmeRes", marginAlignment: "h:center, v:center" })
        ]
    });

    if (map[data.Y] == null)
    {
        map[data.Y] = new Array();
    }
    map[data.Y][data.X] = blockInfo(data);}

Why blockInfo.ownfood is undefine on "button2Rect" even if I assign "data.food" on the blockInfo function and how can I solve this.

Thanks

Pierre Capon
  • 143
  • 1
  • 9
  • 3
    you assign `data.food` to the global variable `ownfood`, not to the property of object `blockInfo` – gawi Jun 25 '17 at 16:27
  • And how can I assign the property of blockInfo ? – Pierre Capon Jun 25 '17 at 16:32
  • 1
    The blockInfo is a function, and in JavaScript the function scope (the 'this') is determined by the caller of the function, so you can't really attach properties from inside. Consider returning an object instead, with the properties you need, or use a variable defined in an upper scope - but global states are not really a good way. – István Rábel Jun 25 '17 at 16:37

1 Answers1

3

First Issue

When you define a variable inside a function scope, that variable is a local variable that you can use inside of that scope, but will not be accessible outside of that scope later on so, just because you did

function hello(){
  var greeting = 'hi';
}

does not mean that you can later access greeting such as by doing

hello.greeting 

Second Issue

In Javascript, functions are similar to classes insofar as you can create instances of functions. blockInfo is a function, not an instance of a function. If you want to create an instance of a function, you can do:

myBlockInfo = new blockInfo(data)

if you simply do

myBlockInfo = blockInfo(data)

without the new keyword, you are not creating an instance of the function (and, furthermore, the value of myBlockInfo will be undefined because the function blockInfo does not return anything).

There is a special variable in Javascript: this. When you are planning on instantiating a function using the new keyword, you gain the ability to use the special variable this inside the function. It is a placeholder for "the current instance of the object". So, if you do

function blockInfo(data){
  this.ownfood = data.food 
}

what you are doing is assigning data.food to any instances of that function you might create. So, when you instantiate the function, you will be creating an instance of the function that has a property, ownfood, which you can access via the instance:

myBlockInfo = new blockInfo(data)
console.log(myBlockInfo.ownfood)
// logs the value of data.food
danyamachine
  • 1,848
  • 1
  • 18
  • 21