benötigen eine Erklärung der Funktion _.bindAll () aus Underscore.js

85

Ich habe einige backbone.js gelernt und viele Fälle gesehen, in denen sie _.bindAll()verwendet werden. Ich habe die gesamte Dokumentationsseite von backbone.js und underscore.js durchgelesen, um ein Gefühl dafür zu bekommen, was es tut, aber ich bin immer noch sehr unklar, was es tut. Hier ist die Erklärung des Unterstrichs:

_.bindAll(object, [*methodNames]) 

Bindet eine Reihe von Methoden an das Objekt, die durch methodNames angegeben werden, um bei jedem Aufruf im Kontext dieses Objekts ausgeführt zu werden. Sehr praktisch für Bindungsfunktionen, die als Ereignishandler verwendet werden sollen, die sonst mit einer ziemlich nutzlosen Funktion aufgerufen würden. Wenn keine methodNames angegeben werden, werden alle Funktionseigenschaften des Objekts daran gebunden.

var buttonView = {
  label   : 'underscore',
  onClick : function(){ alert('clicked: ' + this.label); },
  onHover : function(){ console.log('hovering: ' + this.label); }
};

_.bindAll(buttonView);

jQuery('#underscore_button').bind('click', buttonView.onClick);
=> When the button is clicked, this.label will have the correct value...

Wenn Sie hier helfen können, indem Sie vielleicht ein anderes Beispiel oder eine verbale Erklärung geben, wäre alles willkommen. Ich habe versucht, nach weiteren Tutorials oder Beispielen zu suchen, aber es tauchen keine auf, die dem dienen, was ich brauchte. Die meisten Leute scheinen nur zu wissen, was es automatisch macht ...

Nik So.
quelle
24
Tolle Erklärung: blog.bigbinary.com/2011/08/18/…
jared_flack

Antworten:

66

var Cow = function(name) {
    this.name = name;
}
Cow.prototype.moo = function() {
    document.getElementById('output').innerHTML += this.name + ' moos' + '<br>';
}

var cow1 = new Cow('alice');
var cow2 = new Cow('bob');

cow1.moo(); // alice moos
cow2.moo(); // bob moos

var func = cow1.moo;
func(); // not what you expect since the function is called with this===window
_.bindAll(cow1, 'moo');
func = cow1.moo;
func(); // alice moos
<div id="output" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Leider funktioniert die eigentliche Funktion "Alle binden" nur für Funktionen direkt am Objekt. Um eine Funktion einzuschließen, die im Prototyp definiert ist, müssen Sie diese Funktionsnamen explizit als zusätzliche Argumente an übergeben _.bindAll().

Wie auch immer, Sie wollten eine Erklärung: Grundsätzlich können Sie eine Funktion für ein Objekt durch eine Funktion ersetzen, die denselben Namen und dasselbe Verhalten hat, aber auch an dieses Objekt gebunden ist, also this === theObjectauch ohne es als Methode aufzurufen ( theObject.method()).

DiebMaster
quelle
@ThiefMaster "Übergebe diese Funktionsnamen explizit als zusätzliche Argumente an _.bindAll ()." Tut mir leid, ich lerne immer noch aus Ihrem Beispiel und versuche, die Auswirkungen hier herauszufinden: Sie sagen also, dass die im Prototyp definierten Funktionen nicht automatisch an das Objekt unter _.bindAll gebunden sind, und wenn dies erreicht werden soll, muss man das füttern erster Parameter mit dem Objekt; der zweite Parameter der Funktionsname WENN diese Funktion auf dem Prototyp definiert wurde?
Nik So
9
Dieser Blog-Beitrag von Yehuda Katz erklärt thissehr gut in JavaScript.
Henrik N
9

Die einfachste Erklärung für mich ist die nächste:

initialize:function () { //backbone initialize function
    this.model.on("change",this.render); //doesn't work because of the wrong context - in such a way we are searching for a render method in the window object  
    this.model.on("change",this.render,this); //works fine
    //or 
    _.bindAll(this,'render');
    this.model.on("change",this.render); //now works fine
    //after  _.bindAll we can use short callback names in model event bindings
}
Roman Yudin
quelle
-2

Versuche dies

<input type="button" value="submit" id="underscore_button"/>

<script>
var buttonView = {
    id     : 'underscore',
    onClick: function () {console.log('clicked: ' + this.id)},
    onHover: function () {console.log('hovering: ' + this.id)}
}
_.bindAll(buttonView, 'onClick')
$('#underscore_button').click(buttonView.onClick)
$('#underscore_button').hover(buttonView.onHover)
</script>
Wilderbse
quelle