我正在尝试创建一个类,并将其传递给另一个类,并且我遇到了原型问题。我知道我可以使用bind
来解决这个问题,但我无法找到一种方法让原型方法在实例化时绑定到它的构造函数。这让我有这样的事情:
foo = new obj(); // has foo.method that depends on "this" being bound to obj
// pass foo.method to bar, with it's context bound to foo
bar = new obj2(foo.method.bind(foo)); // obj2 uses foo.method as a "callback" internally. ugly. T_T
这是一个人为的例子:
/**
* Base horn class. To be shared by cars, clowns, braggads, etc.
*/
var Horn = (function(){
var Horn = function (noise){
this.noise = noise;
};
Horn.prototype.sound = function(){
return "*blowing horn* " + this.noise;
};
return Horn; // is there a way to bind here?
})();
/**
* Base car class. Needs a horn.
*/
var Car = (function(){
var Car = function (model, horn) {
this.model = model;
this.horn = horn;
};
Car.prototype.drive = function(){
return "i'm driving in my " + this.model + " " + this.horn();
};
return Car;
})();
/*
* Visualize output
*/
var term = document.getElementById('term');
term.say = function(message){
this.innerHTML += message + "\n";
};
// create a horn for cars.
var carHorn = new Horn('beep beep');
term.say(carHorn.sound()); // *blowing horn* beep beep
// pass the horn to a new Acura
var acura = new Car("acura", carHorn.sound);
term.say(acura.drive()); // i'm driving in my acura *blowing horn* undefined
// Pass the horn to a prius, but bind the horn first
var prius = new Car("prius", carHorn.sound.bind(carHorn)); // whooo bind.
term.say(prius.drive()); //i'm driving in my prius *blowing horn* beep beep
我已经在SO上做了很多阅读(this帖子非常有帮助),但我似乎无法找到一种优雅的方式来做到这一点。
另外,如果我以完全倒退的方式解决这个问题,请告诉我。
答案 0 :(得分:1)
您可以在构造函数中绑定方法:
var Horn = function (noise){
this.noise = noise;
this.sound = this.sound.bind( this );
};
RHS将从原型中读取它,LHS将直接编写它
在对象上,当你引用它时,它会遮挡原型上的那个。您仍然可以使用hornInstance.constructor.prototype.sound
或Horn.prototype.sound
这通常在你别无选择时完成,I.E。传递方法时 作为某个地方的事件听众。在这种情况下,你可以很容易地通过 喇叭对象。
答案 1 :(得分:0)
我通常会按照问题的评论中的建议传递整个对象或函数输出。但是,你问的是可能的。你只是不能拥有原型中的函数,每个实例需要一个单独的(绑定)函数:
var Horn = (function(){
var Horn = function (noise){
this.noise = noise;
this.sound = function(){
return "*blowing horn* " + this.noise;
}.bind(this); // bind here
};
return Horn;
})();