è necessaria una spiegazione della funzione _.bindAll () da Underscore.js


85

Sto imparando alcuni backbone.js e ho visto molti casi in cui _.bindAll()viene utilizzato. Ho letto l'intera pagina della documentazione di backbone.js e underscore.js per cercare di avere un'idea di cosa fa, ma sono ancora molto confuso su cosa fa. Ecco la spiegazione del trattino basso:

_.bindAll(object, [*methodNames]) 

Associa un numero di metodi all'oggetto, specificato da methodNames, da eseguire nel contesto di quell'oggetto ogni volta che vengono richiamati. Molto utile per le funzioni di associazione che verranno utilizzate come gestori di eventi, che altrimenti verrebbero invocate con un this abbastanza inutile. Se non viene fornito alcun methodNames, tutte le proprietà della funzione dell'oggetto verranno associate ad esso.

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...

Se puoi dare una mano qui dando forse un altro esempio o qualche spiegazione verbale, qualsiasi cosa sarebbe apprezzata. Ho provato a cercare più tutorial o esempi, ma non ho trovato nulla che servisse a ciò di cui avevo bisogno. La maggior parte delle persone sembra sapere cosa fa automaticamente ...


Risposte:


67

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>

Sfortunatamente la funzionalità "bind all" effettiva funziona solo sulle funzioni direttamente sull'oggetto. Per includere una funzione definita sul prototipo è necessario passare esplicitamente i nomi di funzione come argomenti aggiuntivi a _.bindAll().

Ad ogni modo, volevi una spiegazione: sostanzialmente ti permette di sostituire una funzione su un oggetto con una funzione che ha lo stesso nome e comportamento, ma è anche legata a quell'oggetto, quindi this === theObjectanche senza chiamarla come metodo ( theObject.method()).


@ThiefMaster "passa quei nomi di funzione esplicitamente come argomenti aggiuntivi a _.bindAll ()." Scusa, sto ancora imparando dal tuo esempio e cerca di capire le sue implicazioni qui: quindi dici che le funzioni definite su prototype non sono automaticamente legate all'oggetto sotto _.bindAll e se si dovesse ottenere questo, è necessario alimentare il primo parametro con l'oggetto; il secondo parametro il nome della funzione SE quella funzione è stata definita sul prototipo?
Nik So

9
Questo post sul blog di Yehuda Katz spiega thismolto bene in JavaScript.
Henrik N

9

La spiegazione più semplice per me è la seguente:

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
}

-2

prova questo

<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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.