我最近开始学习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中。这是我到目前为止所读到的理论,但我在哪里必须使用“自我”?这是方法吗?
答案 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
,我们可以尝试使用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)));
};
};
此代码摘自本书:Secret of the javascript ninja。如果浏览器本身不支持.bind
方法,则此代码可用作填充。