2012-07-22 97 views
1

我很難理解JS中關閉和變量範圍的概念。具體而言,如何訪問類中深度嵌套的styleData變量,然後如何訪問由該類創建的對象?JavaScript關閉和可變範圍

我敢肯定我在這裏還有其他一些錯誤,所以請在你認爲合適的地方加以注意並糾正。謝謝!

var BuildJSON = { 
    convert: function() { 
     $.ajax({ 
      type: "GET", 
      url: "style2.xml", 
      dataType: "xml", 
      success: function(xml) { 
       var styleData = $.xml2json(xml); 
       return styleData; // Do I need to return this somehow? 
      } 
     //How to get access to styleData?? 
     });     
    }, 

    styleData: this.convert(); 
}; 

var myClass = function() { 
    this.info = BuildJSON.styleData; 
}; 

var myObject = new myClass; 

alert(myObject.info.Style[0].name); 
+0

是變量'myObject'和'BuildJSON'事先聲明? – 2012-07-22 23:23:58

+0

之前是什麼?BuildJSON是對象文本,並myObject的是從myClass創建的新對象,對嗎? – 2012-07-22 23:27:39

+0

在上面發佈的代碼之前,如果這兩個變量第一次出現在上面的代碼中,則必須在它們前面放置一個'var',因此:'var BuildJSON = {...'和'var myObject = ...' – 2012-07-22 23:29:07

回答

3

閉包在JavaScript是函數,所以函數範圍內聲明的任何內容都只能在該函數內部可見。

在你的例子中,styleData是本地的,它屬於success函數,不能在其他地方訪問。最簡單的辦法是聲明變量在BuildJSON範圍的頂端,在這種情況下,因爲你聲明對象作爲對象字面可以初始化它作爲對象的屬性:

this.styleData = '', 

... 

success: function(xml) { 
    BuildJSON.styleData = $.xml2json(xml); 
} 

的「問題「,這種方法是styleData是公開的,也許這不是你想要的。如果你想在BuildJSON中使用該變量但不能公開訪問,那麼模塊模式就會出現。

var BuildJSON = (function(){ 
    var styleData = '', // local 
     convert = function(){ ... } // You can use style data here 

    return { 
    convert: convert // Return only stuff you want to be public 
    } 
}()) 
0

我要說的是,最大的問題在這裏更多的是異步編程DUS到AJAX調用則是關於回調本身。

你可以做的一件事就是從ajax回調中明確設置styleData。請注意,如何從外部作用域訪問和修改外部作用域的「that」變量。

var BuildJSON = { 
    convert: function() { 
     var that = this; // inner callbacks get separate "this" 
          // variables so we save the BuildJSON in a separate variable. 
     $.ajax({ 
      type: "GET", 
      url: "style2.xml", 
      dataType: "xml", 
      success: function(xml) { 
       that.styleData = $.xml2json(xml); 
      } 
     });     
    } 
}; 
BuildJSON.convert(); 

雖然這是簡單的事情,它有您只能讀取「styleData」特性轉換運行完成後,你寫的代碼的方式,你沒有辦法知道阿賈克斯後下跌調用已完成(其他輪詢styleData變量與setinterval,但這將是愚蠢的)。

有兩種主要方法可以從異步函數「返回」內部值。一種方法是像$ .ajax本身那樣做,將您的函數轉換爲延續傳遞樣式。通過這種方式,而不是返回styleData導致您收到一個功能你完成計算它

convert: function(onStyleData) { 
    $.ajax({ 
     // ... 
     success: function(xml) { 
      var styleData = $.xml2json(xml); 
      onStyleData(styledata); // <--- 
     } 
    });     
}; 

BuildJSON.convert(function(styledata){ 
    console.log('got styledata', styledata) 
}) 

另一種可能是利用承諾支持JQuery的時候與styledata打電話。像ajax這樣的函數返回特殊的承諾對象,使異步編程更加方便(因爲你可以寫代碼返回值與「返回」,而不是被迫做手動CPS。

我真的不知道他們的名字他們在JQuery中使用這一點,但在Dojo工具包它看起來有點像

var styleDataPromise = dojo.xhr({ 
    url: /*...*/, 
    load: function(data){ 
     return xmlToJSON(xml); 
    } 
}) 

styleDataPromise.then(function(styleData){ 
    console.log('got styledata', styleData) 
})