繁体   English   中英

在回调中访问类属性

[英]Access to a class property in a 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);

我在应该更新模型数据的集合数据中使用回调方法(为简单起见命名回调)。 我的问题是在回调中我没有访问集合属性。 我实际上是在创建一个名为集合的新对象。 在某些时候,我认为我应该使用this ,但由于我将使用 Ajax 调用,因此我必须将其保存this另一个通常称为self的变量中。 到目前为止,这就是我读过的理论,但是我必须在哪里使用self 那是方法吗?

在某些时候,我认为我应该使用“this”,但由于我将使用 Ajax 调用,我将不得不将“this”保存在另一个通常称为“self”的 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;}

一般来说,一个方法不应该关心它是如何被调用的。 如果 Collection 的原型方法中的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)));
      };
};

这段代码摘自这本书: javascript ninja 的秘密 如果浏览器本身不支持.bind方法,此代码可以用作 polyfill。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM