2013-11-24 97 views
0

我最近開始在Javascript中學習模式,並嘗試通過模擬「類」來了解它是如何工作的。所以很可能這個錯誤是由於對如何執行的錯誤理解而出現的。訪問回調中的類屬性

我有以下的一般類:

var Collection = (function(){ 
    function Collection(){ 
     this.collection = {}; 
    } 

    var p = Collection.prototype; 
    p.callback = function(data){collection = data;} 

    return Collection; 
})(); 

API是一個單例類。 Get_Data方法將執行一些Ajax調用,但到目前爲止它只是一個對象。 singleton類是如下:

var WebService = (function(){ 
    var instance; 
    var init = function(){ 
     return { 
      get_data: function(callback){ 
        // Dump data without accessing the Server 
        callback({'id':1234, 'data':"hello world"}) 
      } 
     } 
    } 

    return { 
     get_instance: function(){ 
      if(!instance) 
       instance = init(); 

      return instance; 
     } 
    } 
})(); 

在某些時候,我創建了一個集合類和一些源獲取一些數據(這將是從Web服務,但到目前爲止,我只是用一個對象)。

var collection_objects = new Collection(); 
var api = WebService.get_instance(); 
api.get_data(collection_objects.callback); 

我使用的應該更新模型數據的收集數據的回調方法(名稱回調簡單)。我的問題是,在回調中我沒有訪問收藏屬性。實際上我創建了一個名爲collection的新對象。在某些時候,我認爲我應該使用「this」,但由於我將使用Ajax調用,因此我必須將「this」保存在另一個通常稱爲「self」的vble中。這是迄今爲止我讀過的理論,但我必須在哪裏使用「自我」?這是方法嗎?

+0

添加「var self = this;」在某個地方一級。然後在你的回調函數中使用「self.collection」。 –

+0

@MarvinSmit你是什麼意思與一個級別?因爲我嘗試將它添加到構造函數中,但該對象有兩個屬性:collection和「self」(「self」將包含另一個集合和「self」等)。它創建遞歸對象包含另一個,另一個,等等......是嗎? – kitimenpolku

回答

1

在某一點上,我認爲我應該用「這個」,但因爲我會用 Ajax調用,我將不得不拯救「這個」在另一個vble通常 稱爲「自」

這是一個技巧來克服在JavaScript中的this問題。在我看來,這不如功能緊密耦合到當前上下文以外的變量。

更好的解決方案是使用.bind將上下文綁定爲您的collection_objects。就像這樣:

api.get_data(collection_objects.callback.bind(collection_objects)); 

並使用你的回調this,在這種情況下,this是collection_objects而不是全局窗口對象

p.callback = function(data){ this.collection = data;} 

一般情況下,一個方法不應該關心它是如何的調用。這是非常不直觀的,如果this內Collection的原型方法不引用一個Collection實例。因此,我們應該在Collection實例的上下文中調用該函數。爲了避免忘記使用.bind,我們可以嘗試另一種解決方案與callapply

get_data: function(context,callback){ 
    // Dump data without accessing the Server 
    callback.call(context,{'id':1234, 'data':"hello world"}); 
} 

而且使用這樣的:

api.get_data(collection_objects,collection_objects.callback); 

內部,.bind使用類似於callapply要達到的目標。

Function.prototype.bind = function(){ 
    var fn=this,args=Array.prototype.slice.call(arguments),object=args.shift(); 
    return function(){ 
     return fn.apply(object, 
     args.concat(Array.prototype.slice.call(arguments))); 
     }; 
}; 

此代碼是從書提取:Secret of the javascript ninja。如果瀏覽器本身不支持.bind方法,此代碼可用作填充。

+0

當我使用該功能時,我必須應用該.bind嗎?如果忘記使用.bind方法,是不是很容易出錯? – kitimenpolku

+1

@kitimenpolku:好點。看看我更新的答案 –