JavaScript newbie here. I've searched and searched for answers and can't seem to figure this out. The arrays that I'm passing to a function aren't being passed as references properly. I don't think this is an async issue like many posts allude to but I could be wrong.
I have global arrays that I'm passing to a function. Inside the function, the arrays return their proper values, but when I try to access them outside of the function, they are undefined.
For context, I'm passing 3 arrays that hold the dry-bulb temperature, wet-bulb temperature, and hour that the measurements were taken for later calculations. I've only included a few sample data points 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];
};
run
assigns empty arrays to hour
, db
and wb
. These are variables which are locally scoped to the run
function.
It then calls getData
and passes those arrays as arguments.
Inside getData
new local variables (also named hour
, db
and wb
) are declared and are assigned the three empty arrays that were passed when the function was called.
The function then ignores those values and overwrites them with new arrays (these ones have contents).
It then returns another new array which holds each of those arrays.
This brings us back to run
. The return value of getData
is ignored completely and the original arrays (which are still stored in the hour
, db
and wb
variables that belong to run
) are accessed (but they are still empty).
You can either:
getData
instead of overwriting them. (eg hour = [1,2,3]
may become hour.push(1); hour.push(2); hour.push(3)
). getData
(in which case you don't need to bother assigning values or passing the empty arrays in the first place). You could use an object instead of an array so you can have useful names instead of an order here too. 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];
};
Well, those aren't global variables. The one hour
variable 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 getData
function you are overwriting the local variable (which initially has the value that was passed in by run()
) in the line
hour = [1,2,3];
and from thereon the two variables refer to different arrays.
function getData(hour, db, wb, cities){ }
hour
, db
, etc are references to the initial Arrays.
When you write hour = [1,2,3];
, the hour
local references does not longer point to your desired Array, but to a new Array which you have just constructed: [1,2,3]
. To fix this issue simply push values to the parameters hours.push(1,2,3);
so you won't overwrite your references.
This is the same problem that occurs when you do:
a = {x : 1};
function setX(obj) {
obj = {x: 2};
}
function correctSetX(obj) {
obj.x = 2;
}
The setX
function will do nothing, while the correctSetX
will correclty a to {x : 2}
.
Thank you all for your help! I've posted how I edited my code to get it to work based on the comments. A couple things:
-I've moved all variables to be local in the getData() function. At least one of the comments gave the impression that it is better practice to keep variables local (forgive me, I am not a CSE guy by training, but I appreciate the tips and patience on your behalf)
-I wasn't able to simply use the .push method because the amount of data caused an error. (there are at least 8760 measurements per year) I can't remember the exact error but it was related to stack limits
-At the suggestion of Quentin, I instead created a dataSet object that had array properties. This object is what is returned by the getData function. Thank you again, this was a much better way to handle this
Sample 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
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.