necesita una explicación de la función _.bindAll () de Underscore.js

85

He estado aprendiendo algunos backbone.js y he visto muchos casos en los que _.bindAll()se usa. He leído toda la página de documentación de backbone.js y underscore.js para intentar tener una idea de lo que hace, pero todavía estoy muy confuso en cuanto a lo que hace. Aquí está la explicación del subrayado:

_.bindAll(object, [*methodNames]) 

Vincula una serie de métodos en el objeto, especificados por methodNames, para que se ejecuten en el contexto de ese objeto cada vez que se invocan. Muy útil para vincular funciones que se utilizarán como controladores de eventos, que de otro modo se invocarían con un this bastante inútil. Si no se proporcionan MethodNames, todas las propiedades de la función del objeto se vincularán a él.

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

Si puede ayudar aquí dando otro ejemplo tal vez o alguna explicación verbal, cualquier cosa será apreciada. Traté de buscar más tutoriales o ejemplos, pero ninguno resultó que sirviera para lo que necesitaba. La mayoría de la gente parece saber lo que hace automáticamente ...

Nik So
fuente
24
Gran explicación: blog.bigbinary.com/2011/08/18/…
jared_flack

Respuestas:

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>

Desafortunadamente, la funcionalidad de "vincular todo" solo funciona en funciones directamente en el objeto. Para incluir una función definida en el prototipo, debe pasar esos nombres de función explícitamente como argumentos adicionales a _.bindAll().

De todos modos, querías una explicación: Básicamente te permite reemplazar una función en un objeto con una función que tiene el mismo nombre y comportamiento, pero que también está vinculada a ese objeto, this === theObjectincluso sin llamarlo como método ( theObject.method()).

ThiefMaster
fuente
@ThiefMaster "pasa esos nombres de función explícitamente como argumentos adicionales a _.bindAll ()". Lo siento, sigo aprendiendo de su ejemplo e intente descubrir sus implicaciones aquí: entonces dice que las funciones definidas en el prototipo no están vinculadas automáticamente con el objeto en _.bindAll y si uno lograra esto, necesita alimentar el primer parámetro con el objeto; el segundo parámetro el nombre de la función SI esa función se definió en el prototipo?
Nik So
9
Esta publicación de blog de Yehuda Katz explica thismuy bien en JavaScript.
Henrik N
9

La explicación más simple en cuanto a mí es la siguiente:

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

prueba esto

<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>
guisante
fuente