2012-12-26 61 views
0

以下是我正在處理的代碼。我想知道爲什麼,當我在函數中更改變量ttt時,更改不會停留在函數之外?我已經在最高層宣佈它爲var ttt = new Array;Javascript:如何修改函數內的全局變量?

另外,爲什麼我不能在函數中使用變量i

代碼:

所有的
client.on('connection', function() 
    { 
     var sss; 
     var aaa; 

      console.log('Connected'); 

     for (i = 0 ; i < 120 ; i++) 
      ttt[i] = 0; 

     for (i = 0 ; i < 9 ; i++) 
     { 
       client.getMatchHistory(434582, function(err, result)   
      { 
       sss = JSON.stringify(result); 
       var myObject = eval('(' + sss + ')'); 
       console.log (myObject.object.data[i].object.value); 

       ttt[myObject.object.data[i].object.value]++; 
      }); 

     } 

      for (i = 0 ; i < 120 ; i++) 
       console.log ("Record" + i + " Successes: " + ttt[i]); 

    }); 
+0

你能澄清一下你的問題嗎?當你說「變化不在功能之外」時,你是什麼意思?另外,當你問:「爲什麼我不能在函數中使用變量'i'?」是什麼意思? – seliopou

+0

ttt [myObject.object.data [i] .object.value] ++; 這行應該改變ttt數組。而且它在功能中。但在功能之外,稍後: console.log(「Record」+ i +「Successes:」+ ttt [i]);無論如何, 僅顯示爲0。 至於我不工作...在函數中,我在console.log(myObject.object.data [i] .object.value);總是返回未定義和崩潰。如果我用一個數字替換我,比如0,它就可以工作。爲什麼不能將函數引用/識別爲for(i = 0; i <9; i ++) –

回答

2

正如你指出的,還有你的代碼兩個獨立的問題,他們都有點相關。首先,ttt正在全球修改。問題在於你在修改發生之前檢查它們。我懷疑client.getMatchHistory()正在進行異步調用。有沒有保證所有在第二for循環的異步操作將完成你的時間執行第三for循環,在那裏你讀的陣列中執行。

第二個問題是範圍之一,但它不是全球範圍那是你的問題。由於client.getMatchHistory()是異步的,一旦循環完成執行,將調用回調。一旦循環完成執行i將具有值10。可能這不是你想要的。您需要創建一個回調產生功能,即利用了i值,並返回一個可以作爲一個回調函數。就像這樣:

然後你應該使用這樣的循環體:

client.getMatchHistory(434582, make_callback(i)) 

這將捕獲的i值在當前迭代和生成的回調將使用值執行時。這應該可以解決您的問題i

0

首先,所有的全局變量都是有效的「窗口」對象字段,所以你可以使用window.ttt,以確保您使用的不是本地的全局變量。此代碼應該工作,所以你在開發者工具中嘗試它?調試器對這種變量的存在性有什麼看法?

至於變量i:當然,你可以使用它,但它更好地在本地使用它,定義風險價值我;'在函數的頂部不會破壞全局名稱空間。

+0

所有有效全局變量都是window對象的屬性並不完全正確。在所有其他腳本包含之前用'var'聲明的變量實際上是「全局的」(即:它們可以被隨後聲明/加載的所有代碼訪問和修改),但它們絕對不是'window'對象的屬性。 –

+0

@ David-SkyMesh這是不正確的。即使你用'var'聲明一個全局變量,例如'var my_global',你仍然可以通過'window.my_global'訪問它。 – seliopou

+0

@seliopou不,你不能。我鼓勵你先檢查一下。 –

0

client.getMatchHistory可能異步請求,你想到的是循環之後,你會充滿ttt陣列,以達致這你必須讓這最後的循環步驟之後運行的處理程序:

var afterloop=function() { 
    for (var i = 0 ; i < 120 ; i++) 
     console.log ("Record" + i + " Successes: " + ttt[i]); 
} 
for (var i = 0 ; i < 120 ; i++) 
     ttt[i] = 0; 

var i_final=0; 
for (var i = 0 ; i < 9 ; i++) 
     { 
      var i=i; //localise i 
      client.getMatchHistory(434582, function(err, result)   
      { 
       i_final++; 
       sss = JSON.stringify(result); 
       var myObject = eval('(' + sss + ')'); 
       console.log (myObject.object.data[i].object.value); 

       ttt[myObject.object.data[i].object.value]++; 
       if (i_final>8) {afterloop();} 
      }); 

     } 
樣品中

,完成請求i_final計數,它們可以以任意順序進行,由於異步,所以決定來運行afterloop(),當應最後後執行i_final計數比去年執行的請求越多,運行功能,當你不能指i請求完成。

注:請使用全局變量儘可能少,在你的代碼中使用了全局i沒有任何理由

+0

窗口上的參考錯誤。我沒有在瀏覽器中運行這個,但使用Node.js ...是一個問題? –

+0

爲什麼你需要gloval var呢?添加'var ttt = [];'調用函數的地方 –

+0

一些非常好的響應。謝謝。篩選一切。順便說一句,eicto,你的解決方案工作,我只有3天編程JS,但這真的幫助我瞭解更多。 –

相關問題