preciso de explicação da função _.bindAll () de Underscore.js

85

Tenho aprendido alguns backbone.js e já vi muitas instâncias em que _.bindAll()é usado. Eu li toda a página de documentação backbone.js e underscore.js para tentar ter uma ideia do que ele faz, mas ainda estou muito confuso sobre o que ele faz. Aqui está a explicação do sublinhado:

_.bindAll(object, [*methodNames]) 

Vincula vários métodos no objeto, especificados por methodNames, para serem executados no contexto desse objeto sempre que forem chamados. Muito útil para funções de ligação que serão usadas como tratadores de evento, que de outra forma seriam invocadas com um this bastante inútil. Se nenhum methodNames for fornecido, todas as propriedades da função do objeto serão associadas a ele.

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 você puder ajudar aqui dando outro exemplo, talvez ou alguma explicação verbal, qualquer coisa seria apreciada. Tentei pesquisar mais tutoriais ou exemplos, mas não encontrei nada que atendesse ao que eu precisava. A maioria das pessoas parece saber o que ele faz automaticamente ...

Nik So
fonte
24
Ótima explicação: blog.bigbinary.com/2011/08/18/…
jared_flack

Respostas:

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>

Infelizmente, a funcionalidade real de "vincular tudo" funciona apenas nas funções certas no objeto. Para incluir uma função definida no protótipo, você precisa passar esses nomes de função explicitamente como argumentos adicionais para _.bindAll().

De qualquer forma, você queria uma explicação: Basicamente, ele permite que você substitua uma função em um objeto por uma função que tem o mesmo nome e comportamento, mas também está ligada a esse objeto, this === theObjectmesmo sem chamá-lo como um método ( theObject.method()).

ThiefMaster
fonte
@ThiefMaster "passe esses nomes de função explicitamente como argumentos adicionais para _.bindAll ()." Desculpe, ainda aprendendo com seu exemplo e tente descobrir suas implicações aqui: então você diz que as funções definidas no protótipo não são automaticamente vinculadas ao objeto em _.bindAll e se alguém conseguir isso, é necessário alimentar o primeiro parâmetro com o objeto; o segundo parâmetro é o nome da função SE essa função foi definida no protótipo?
Nik So
9
Esta postagem no blog de Yehuda Katz explica thismuito bem em JavaScript.
Henrik N
9

A explicação mais simples para mim é a seguinte:

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
fonte
-2

tente isso

<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>
ervilha-brava
fonte