JavaScript: returned global array variable undefined

JavaScript newbie here. I have searched and searched for answers and don't seem to figure it out. The arrays I pass to the function are not being passed as references correctly. I don't think this is an asynchronous problem like many posts have, but I could be wrong.

I have global arrays that I pass to functions. Inside the function, the arrays return their own values, but when I try to access them outside the function, they are undefined.

In context, I go through 3 arrays that maintain dry bulb temperature, wet hood temperature and hour so that measurements are taken for subsequent calculations. I've included some sample data for brevity. Sample code below:

function run(){
    var hour = [];
    var db = [];
    var wb = [];
    var cities = ["AB Edmonton","MI Detroit"];
    getData(hour, db, wb, cities); 
    //this shows undefined, although within getData it is accurate data
    alert(hour[1]);
}

function getData(hour, db, wb, cities){
    //i= drop-down selection index, set to zero for testing
    i=0;

    switch(cities[i]) {
        case "AB Edmonton":
            hour = [1,2,3];
            db = [15,18,21];
            wb = [10,13,20];
            break;
        //case "MI Detroit":....
    }

    //this shows accurate values in the alert window
    alert(cities[i] + " at hour:" + hour[i] + " the temp is:" + db[i]);

    return [hour, db, wb];
};

      

+3


source to share


4 answers


run

assigns empty arrays hour

, db

and wb

. These are variables that are locally bound to the function run

.

It then calls getData

and passes those arrays as arguments.

Internally getData

, new local variables (also called hour

, db

and wb

) are declared and assigned to three empty arrays that were passed in when the function was called.

The function then ignores these values ​​and overwrites them with new arrays (they have content).

Then it returns another new array that contains each of those arrays.



This brings us back to run

. The return value is getData

completely ignored, and the original arrays (which are still stored in variables hour

, db

and wb

owned run

) are available (but they are still empty).

You can:

  • Manipulate existing arrays internally getData

    instead of overwriting them. (for example, it hour = [1,2,3]

    can become hour.push(1); hour.push(2); hour.push(3)

    ).
  • Use a return value getData

    (in this case, you don't have to worry about assigning values ​​or passing empty arrays in the first place). You can use object instead of array so you can have useful names instead of order here.

Such:

function run(){
    var cities = ["AB Edmonton","MI Detroit"];
    var data = getData(cities); 
    alert(data.hour[1]);
}

function getData(cities){
    //i= drop-down selection index, set to zero for testing
    var i=0; // Use locally scoped variables where possible
    var hour, db, wb;

    switch(cities[i]) {
        case "AB Edmonton":
            hour = [1,2,3];
            db = [15,18,21];
            wb = [10,13,20];
            break;
        //case "MI Detroit":....

    //this shows accurate values in the alert window
    alert(cities[i] + " at hour:" + hour[i] + " the temp is:" + db[i]);

    return { hour: hour, db: db, wb: wb];
};

      

+3


source


Well, these are not global variables. One variable hour

is local to run()

, in which it is declared with var

, the other is local to getData

, in which it is declared as a parameter.

In your function, getData

you are overwriting the local variable (which initially has the value that was passed in run()

) in the line



 hour = [1,2,3];

      

and hence the two variables refer to different arrays.

+1


source


function getData(hour, db, wb, cities){ }

      

hour

, db

etc. are references to initial arrays.

When you write hour = [1,2,3];

, local references hour

do not indicate more on your desired array, and a new array that you just created: [1,2,3]

. To fix this problem, just hours.push(1,2,3);

put values ​​in the parameters so that you don't overwrite your links.

This is the same problem that comes up when you do:

a = {x : 1};
function setX(obj) {
  obj = {x: 2};
}
function correctSetX(obj) {
  obj.x = 2;
}

      

The function will setX

do nothing, but correctSetX

will match a in {x : 2}

.

0


source


Thanks everyone for your help! I posted how I edited my code to make it work based on comments. A couple of things:

- I moved all the variables to the local getData () function. At least one of the comments gave the impression that it is better to save variables locally (forgive me, I'm not a CSE guy, but I appreciate the advice and patience on your behalf).

-I couldn't just use the .push method because the amount of data generated the error. (there are at least 8760 measurements per year) I can't remember the exact error, but it was related to stack limits

- In Quentin's suggestion, I created a dataSet object instead that had array properties. This object is what the getData function returns. Thanks again, this was a much better way to handle this.

Example below (with limited data):

function run(){

    //get data
    var dataSet = getData(); 
    //test the result on the 2 hour reading
    alert(dataSet.hour[1]); 
}

function getData(){
//i= drop-down selection index, set to zero for testing
var i=0;
var hour,db,wb;
var cities = ["AB Edmonton","MI Detroit"];
switch(cities[i]){

    case "AB Edmonton":
        hour = [1,2,3];
        db = [10,11,12];
        wb = [13,14,15];
        break;
    //case "MI Detroit":...
} //end of switch

return {hour: hour, db: db, wb: wb};
}; //end of getData

      

0


source







All Articles