2013-11-24 60 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:好点。看看我更新的答案 –