访问回调中的类属性

时间:2013-11-24 12:06:49

标签: javascript ajax javascript-events jquery-callback

我最近开始学习Javascript中的模式,并试图通过模拟“类”来理解它是如何工作的。所以很可能这个错误即将到来,因为对它的执行方式了解不足。

我有以下一般课程:

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

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

    return Collection;
})();

Api是一个单身人士类。 Get_Data方法将执行一些Ajax调用,但到目前为止它只是一个对象。单身人士课程如下:

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;
        }
    }
})();

在某些时候,我创建一个Collection类并从某个源获取一些数据(它将来自Web服务,但到目前为止我只是使用了一个对象)。

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

我在应该更新模型数据的集合数据中使用了一个回调方法(简单地称为回调)。我的问题是在回调中我没有访问集合属性。我实际上正在创建一个名为collection的新对象。在某些时候,我认为我应该使用“this”,但由于我将使用Ajax调用,我将不得不将“this”保存在另一个通常称为“self”的vble中。这是我到目前为止所读到的理论,但我在哪里必须使用“自我”?这是方法吗?

1 个答案:

答案 0 :(得分:1)

  

在某些时候,我认为我应该使用“this”,但是因为我会使用   一个Ajax调用,我将不得不在另一个vble中保存“this”   被称为“自我”

这是克服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;}

一般来说,一种方法不应该关注它是如何调用的。如果Collection的prototype方法中的this没有引用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方法,则此代码可用作填充。