web-dev-qa-db-fra.com

besoin d'explication de la fonction _.bindAll () de Underscore.js

J'ai appris quelques backbone.js et j'ai vu de nombreuses instances où _.bindAll() est utilisé. J'ai lu l'intégralité de la page de documentation de backbone.js et underscore.js pour essayer d'avoir une idée de ce qu'il fait, mais je suis toujours très flou quant à ce qu'il fait. Voici l'explication du soulignement:

_.bindAll(object, [*methodNames]) 

Lie un certain nombre de méthodes sur l'objet, spécifiées par methodNames, à exécuter dans le contexte de cet objet chaque fois qu'elles sont appelées. Très pratique pour les fonctions de liaison qui vont être utilisées comme gestionnaires d'événements, qui autrement seraient invoquées avec un ceci assez inutile. Si aucun nom de méthode n'est fourni, toutes les propriétés de la fonction de l'objet lui seront liées.

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 vous pouvez aider ici en donnant peut-être un autre exemple ou une explication verbale, tout serait apprécié. J'ai essayé de rechercher plus de tutoriels ou d'exemples, mais aucun ne correspond à ce dont j'avais besoin. La plupart des gens semblent savoir ce qu'il fait automatiquement ...

83
Nik So
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>

Malheureusement, la fonctionnalité "lier tous" ne fonctionne que sur les fonctions directement sur l'objet. Pour inclure une fonction définie sur le prototype, vous devez transmettre ces noms de fonction explicitement en tant qu'arguments supplémentaires à _.bindAll().

Quoi qu'il en soit, vous vouliez une explication: Fondamentalement, cela vous permet de remplacer une fonction sur un objet par une fonction qui a le même nom et le même comportement, mais qui est également liée à cet objet, donc this === theObject Même sans l'appeler en tant que (theObject.method()).

65
ThiefMaster

L'explication la plus simple quant à moi est la suivante:

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
}
9
Roman Yudin