2015-05-16 107 views
3

JavaScript newbie here。我搜索并搜索了答案,似乎无法弄清楚。我传递给函数的数组不能作为引用正确传递。我不认为这是一个像许多帖子暗示的异步问题,但我可能是错的。我有传递给函数的全局数组。在函数内部,数组返回它们的正确值,但是当我尝试在函数外部访问它们时,它们是未定义的。JavaScript:全局数组变量返回undefined

对于上下文,我传递了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]; 
}; 
+0

可以传递城市到你的'getData'功能或定义它的功能外。就目前而言,城市只在'run'内定义,'getData'不能访问它。确保查看关闭。 – Dom

+1

但它们不是全局数组。你已经在run函数中指定了它们,所以它们只有这个范围。 –

+0

如果你没有得到返回的数据,为什么你会返回它们? – Cristy

回答

3

run分配空阵列hourdbwb。这些是局部范围到run函数的变量。

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

里面getData新的局部变量(又称hourdbwb)声明和分配函数被调用时所传递的三个空数组。

然后,该函数将忽略这些值和覆盖它们与新的阵列(这些的有内容)。然后它返回另一个保存每个数组的新数组。

这使我们回到rungetData的返回值被完全忽略,原始数组(仍存储在属于runhour,dbwb变量中)被访问(但它们仍为空)。

您可以:

  • 操纵现有阵列内getData而不是覆盖它们。 (例如hour = [1,2,3]可能变成hour.push(1); hour.push(2); hour.push(3))。
  • 使用返回值getData(在这种情况下,您不需要麻烦分配值或首先传递空数组)。你可以使用一个对象而不是一个数组,所以你可以在这里使用有用的名字而不是命令。

这样的:

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

哦,那是不是全局变量。一个hour变量是局部的run()其中声明为var,另一个是本地getData其中它被声明为参数。

在你getData功能要覆盖局部变量(最初具有由run()传递的值)中的线

hour = [1,2,3]; 

和从在其上的两个变量是指不同的阵列。

0
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将correclty一到{x : 2}

0

谢谢大家的帮忙!我已经发布了如何编辑我的代码以使其基于评论工作。几件事情:

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

-I wasn'能够简单地使用.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