JavaScript: 全局数组变量返回未定义

JavaScript: global array variable returned undefined

JavaScript 这里是新手。我已经搜索并搜索了答案,但似乎无法弄清楚。我传递给函数的数组没有作为引用正确传递。我不认为这是一个像许多帖子提到的异步问题,但我可能是错的。

我有要传递给函数的全局数组。在函数内部,数组 return 它们的正确值,但是当我尝试在函数外部访问它们时,它们是未定义的。

对于上下文,我传递了 3 个数组,它们保存干球温度、湿球温度和进行测量的时间以供以后计算。为了简洁起见,我只包含了几个样本数据点。示例代码如下:

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 将空数组分配给 hourdbwb。这些是 run 函数局部作用域的变量。

然后调用 getData 并将这些数组作为参数传递。

getData 内声明了新的局部变量(也命名为 hourdbwb)并分配了函数时传递的三个空数组被调用了。

函数然后忽略这些值并新数组覆盖它们(这些有内容)。

然后 return 是另一个新数组,其中包含每个数组。

这让我们回到 rungetData 的 return 值被完全忽略,原始数组(仍然存储在 hourdbwb 属于 run) 被访问(但它们仍然是空的)。

您可以:

  • 处理 getData 中的现有数组,而不是覆盖它们。 (例如 hour = [1,2,3] 可能会变成 hour.push(1); hour.push(2); hour.push(3))。
  • 使用 getData 的 return 值(在这种情况下,您无需首先费心分配值或传递空数组)。您可以使用对象而不是数组,这样您也可以使用有用的名称而不是此处的顺序。

这样的:

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];
};

嗯,这些不是全局变量。一个 hour 变量是 run() 的局部变量,它在其中用 var 声明,另一个是 getData 的局部变量,它在其中被声明为参数。

在您的 getData 函数中,您正在覆盖

行中的局部变量(最初具有 run() 传入的值)
 hour = [1,2,3];

从此两个变量引用不同的数组。

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

hourdb 等是对初始数组的引用。

当你写hour = [1,2,3];时,hour局部引用不再指向你想要的数组,而是指向你刚刚构造的新数组:[1,2,3]。要解决此问题,只需将值推送到参数 hours.push(1,2,3); 这样您就不会覆盖您的引用。

这与您执行以下操作时出现的问题相同:

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

setX 函数什么都不做,而 correctSetX 会更正为 {x : 2}

谢谢大家的帮助!我已经发布了我如何根据评论编辑我的代码以使其正常工作。几件事:

-我已将所有变量移动到 getData() 函数中的局部变量。至少有一条评论给人的印象是将变量保持在本地是更好的做法(请原谅我,我不是经过培训的 CSE 人员,但我代表您感谢提示和耐心)

-我无法简单地使用 .push 方法,因为数据量导致错误。 (每年至少有 8760 次测量)我不记得确切的错误,但它与堆栈限制有关

-在 Quentin 的建议下,我创建了一个具有数组属性的数据集对象。该对象是 getData 函数返回的对象。再次感谢您,这是处理此问题的更好方法

示例如下(数据有限):

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