2015-05-16 106 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