这可能是重复的,如果是的话,我道歉。我已经查看了几个问题,并且没有找到一个与我的情况完全匹配的问题(这可能是一个不好的开头)。
我有一个班级,比如RandomClass
,定义如下
function RandomClass(id){
this._id = id;
}
RandomClass.prototype.getID = function(){
return this._id;
}
var rc = new RandomClass(1);
rc.getID(); //returns 1, as expected
假设我想定义一组处理程序,并将它们保存在RandomClass的子对象(继续使用原型)中。 我对原型的了解有些限制,所以如果下一步是非常糟糕的形式,请道歉。
RandomClass.prototype.handlers = {};
RandomClass.prototype.handlers.HandlerOne = function(){
console.log("Handler one calling from ID: "+this._id);
//the context is not the context of RandomClass, but of RandomClass.prototype.handlers!
}
rc.handlers.HandlerOne(); //prints "Handler one calling from ID: unknown"
同样,也许这是一个糟糕的形式,但是我有几个需要调用的处理程序,这样做可以简化代码:
var handler = "one of many many handlers returned from an ajax request";
rc.handlers[handler]();
所以,我的问题是如何让HandlerOne的上下文成为RandomClass的上下文而不是处理程序?我想继续使用原型,因为那样的话不会多次克隆(如下例所示):
function RandomClass(id){
this._id = id;
this._handlers = {};
}
function HandlerOne(){
console.log("Handler one calling from ID: "+this._id);
}
var rc = new RandomClass(1);
rc._handlers["HandlerOne"] = HandlerOne.bind(rc);
rc._handlers["HandlerOne"]() //prints as expected, but I believe performance is much worse here
答案 0 :(得分:1)
可以满足你这样做,而不是绑定上下文尝试将其作为参数传递。
function RandomClass(id){
this._id = id;
this._handlers = {};
}
function HandlerOne(instance){
var parentScope = instance;
console.log("Handler one calling from ID: "+parentScope._id);
}
//call it like this
var rc = new RandomClass(1);
rc._handlers["HandlerOne"] = HandlerOne;
rc._handlers["HandlerOne"](rc)
答案 1 :(得分:1)
您可以简单地将Handlers
设为自己的类。请注意,您不应该像我在下面的示例中那样访问类之外的私有成员。您必须公开正确的公共API,以使对象协同工作而不会违反封装。
function RandomClass(id){
this._id = id;
this.handlers = new Handlers(this);
}
function Handlers(randomClassInstance) {
this._randomClassInstance = randomClassInstance;
}
Handlers.prototype = {
constructor: Handlers,
handlerOne: function () {
console.log("Handler one calling from ID: "+ this._randomClassInstance._id);
}
};
然后你可以这样做:
var rnd = new RandomClass('test');
rnd.handlers.handlerOne(); //Handler one calling from ID: test
答案 2 :(得分:0)
此时提交的两个答案都是很好的替代方案(我认为是可以接受的),但是我已经决定采用另一种方式(这导致对我的代码进行最少量的修改:)。
与@ BlaShadow的答案类似,我只是使用Javascript的parentScope
方法传递正确的上下文,而不是传递上下文并设置function.call()
变量。
function RandomClass(id){
this._id = id;
}
function.prototype.handlers = {}
function.prototype.handlers.HandlerOne = function(data){
console.log("Handler one calling from ID: "+this._id+" with data: "+data);
}
var rc = new RandomClass(1);
rc.handlers.HandlerOne.call(rc, {"some": "data"});
//prints "Handler one calling from ID: 1 with data { "some" : "data" }