need explanation of the _.bindAll() function from Underscore.js

Javascriptbackbone.jsunderscore.js

Javascript Problem Overview


I've been learning some backbone.js and I've seen plenty of instances where _.bindAll() is used. I have read through the entire backbone.js and underscore.js documentation page to try to get a sense of what it does, but I still am very fuzzy as to what it does. Here is underscore's explanation:

> _.bindAll(object, [*methodNames]) > > Binds a number of methods on the > object, specified by methodNames, to > be run in the context of that object > whenever they are invoked. Very handy > for binding functions that are going > to be used as event handlers, which > would otherwise be invoked with a > fairly useless this. If no methodNames > are provided, all of the object's > function properties will be bound to > it. > > 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...

If you can help out here by giving another example perhaps or some verbal explanation, anything would be appreciated. I tried to search for more tutorials or examples, but nil turn up that serve what I needed. Most people seem to just know what it does automatically...

Javascript Solutions


Solution 1 - Javascript

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>

Unfortunately the actual "bind all" functionality only works on functions right on the object. To include a function that is defined on the prototype you need to pass those function names explicitely as additional arguments to _.bindAll().

Anyway, you wanted an explanation: Basically it allows you to replace a function on an object with a function that has the same name and behaviour, but is also bound to that object, so this === theObject even without calling it as a method (theObject.method()).

Solution 2 - Javascript

The simplest explanation as for me is the next:

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
}

Solution 3 - Javascript

try this

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNik SoView Question on Stackoverflow
Solution 1 - JavascriptThiefMasterView Answer on Stackoverflow
Solution 2 - JavascriptRoman YudinView Answer on Stackoverflow
Solution 3 - JavascriptwildpeaView Answer on Stackoverflow