Array question in JS


#1

I’m building a p5 library and I’m new to JavaScript. I’m confused by the JavaScript closure and array system. I don’t understand why I get undefined object “field” in for loops.

Ps: I’m using the math.js eval to translate String to function.

Here is my code

p5.prototype.vectorField = function (fx,fy,size){

    let field = new Array();

    // this is correct.
    console.log(Array.isArray(field));

    if( typeof fx == "string" ){
        for(let i = 0; i < size; i++){
            let scopex = {x:i};
            let x = math.eval(fx,scopex);
            for(let j = 0; j<size; j++){
                let scopey = {y:j};
                let index = i+(j*size);
                let y = math.eval(fy,scopey);

		// but I get error here!
                if (!(index in field)){

		// and here!
                 field.push([]);
                }
                field[index].push(p5.Vector(x,y,0));
            }
        }
    }

    console.log(field);
    return field;
};

And it throws error like this : “Object doesn’t support property or method ‘push’”


#2

I don’t think you have to reassign field; it should only be:

field.push([]);

#3

Yes you’re right. but it still gives the same error.


#4

Can I ask you to specify which error? You have two.

If it was the first error, I think you’re misusing the in operator. Looking at the docs here, it seems that it only applies to dictionaries (although if you’re coming from Python I understand the confusion). However, this is the first time I’ve ever heard of the in operator, so correct me if I’m wrong.


#5

I don’t think it’s the in operator causes this. It works as an array length tester(there is an example it in the doc) Also I tried to delete the " if( … to … )" line then the push() error just pop up.

I noticed the variable"field" just lost its Array property after two iterations disregarding if it is empty or not.


#6

Hm, if this doesn’t work, I’ll give it a go on my own computer, but perhaps try changing field into a (less) local variable by declaring it as a var? I don’t know what the nuances of let are, but it’s worth a try…

EDIT: Look like let is super-local (for lack of a better term

EDIT-EDIT: Nvm. I’m dumb. Still, try changing it to var


#7

Um. I’ve tried it. No luck. I’ve been stuck here for two days when I tried and learned many things. :joy:

If you don’t mind to try it, you might need the math.js to get it run.

Thank you and cheers!


#8

Notice the math.js library is not in question here. You can remove it from your provided code so to focus in your actual function.

If you want to manage an array of objects with a JSON structure consider checking JSONArray.

To revise functionality of the in operator and push() function in Javascript, you can check their respective docs: in and push. Important to note that push() does not return the new array but the new size.

Your question is really not based on the paradigm of closures as you have states in the title. You should edit your question so to reflect the content of your post. You are working with arrays and pushing values to it… properly.

One sample code that could be useful to you is shown below.

Kf


function setup() {

  let size = 10;
  let field =[]; 

  for (let i = 0; i < size; i++) {
    field.push([0]);
    let x = i;
    for (let j = 0; j<size; j++) {

      let index = i+(j*size);
      index*45
        let y = j;

      if ((field[x]==null)) {
        field[x] = new Array();
      }
      field[x][y] = ([x, y, 0]);
      console.log(index + " ==> " +field.length + '   :   ' + field[x][y]);
    }
  }

  console.log(field);
}

function draw() {
}

#9

your code works thanks. I thought it was somehow a compatibility and closure issue, because it works when I tested it alone. Sorry about that, I’m a newbie in JS.

But I still don’t quite understand why my .push([]) (without a return) doesn’t work there. because, when I do this it works fine:

let a = new Array();
a.push([]);
a[0] = ['cat', 'dog'];