[英]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
,我们可以尝试使用call
或apply
的另一种解决方案:
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
使用诸如call
或apply
之类的东西来实现目标。
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.