2013-06-20 27 views
1

我想創建一個類,並將其傳遞給另一個類,並且我遇到了原型問題。我知道我可以使用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 

JS Bin

我已經做了很多的SO閱讀(this職位是非常有幫助),但我似乎無法找到一個優雅的方式來做到這一點。另外,如果我以完全倒退的方式討論這個問題,請告訴我。

+2

你爲什麼不傳遞'Horn',而不是一個'Horn'方法到'Car'構造函數?然後,你會使用'this.horn.sound()'而不是'this.horn()' – Ian

+0

*「,但我不能找出一種方法讓原型方法綁定到實例化的構造函數上。」* Inside在構造函數中,您可以迭代所有原型方法,並將它們綁定到實例的相同屬性名稱,即'this [method] = this [method] .bind(this)'。當然,這爲每個實例創建了每種方法的新副本,這種方法首先破壞了使用'prototype'的目的。我不會這樣做。 –

+0

@ian理想情況下''car.horn''可以是任何函數(即使是匿名函數),所以''Car''''''''''可以在不知道函數名稱的情況下調用它。 –

回答

1

您可以在構造函數中綁定的方法:

var Horn = function (noise){ 
    this.noise = noise; 
    this.sound = this.sound.bind(this); 
}; 

的RHS將從原型閱讀和LHS將它直接寫在對象上 ,它將陰影的原型之一,當你參考它。您仍然可以使用hornInstance.constructor.prototype.soundHorn.prototype.sound引用未綁定的版本。

這通常是在您沒有選擇的情況下完成的,但是,I.E.在某處傳遞方法 作爲事件偵聽器時。在這種情況下,您可以輕鬆通過 喇叭對象。

+0

假設我們幾乎是同步的! :)但是你的答案假設你還有一個原型方法?我不明白爲什麼它需要了。 – bfavaretto

+0

@bfavaretto嗯在技術上不需要。但有些人和我更喜歡縮減縮進級別,並保持構造器簡單。 – Esailija

+0

我不能爭辯說,你的版本看起來更乾淨。 – bfavaretto

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; 
})(); 

http://jsfiddle.net/5xcHG/

相關問題