Underscore.js中的_.bindAll()函数需要解释。

85

我一直在学习backbone.js,看到很多地方都用到了_.bindAll(),我已经阅读过整个backbone.js和underscore.js的文档页面,试图理解它的作用,但我仍然不太清楚。这是underscore的解释:

_.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...
如果你能提供另一个示例或一些口头解释,将不胜感激。我尝试搜索更多的教程或示例,但没有符合我的需求的结果。大多数人似乎都自动知道它的作用...

24
很好的解释:http://blog.bigbinary.com/2011/08/18/understanding-bind-and-bindall-in-backbone.html - jared_flack
3个回答

68

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>

很遗憾,实际的“全部绑定”功能只适用于对象上的函数。如果要包含在原型上定义的函数,则需要将这些函数名称作为额外参数显式传递给_.bindAll()
无论如何,您想要解释:基本上,它允许您使用具有相同名称和行为的函数替换对象上的函数,但也将其绑定到该对象,因此即使不将其调用为方法(theObject.method()),this === theObject

@ThiefMaster "明确将这些函数名作为附加参数传递给_.bindAll()。" 很抱歉,我还在从你的例子中学习,并试图弄清楚它的含义:所以你说,在 _.bindAll 下定义的原型函数不会自动绑定到对象上,如果想要实现这一点,需要将第一个参数设置为对象;如果该函数是在原型上定义的,则将第二个参数设置为函数名? - Nik So
9
这篇由Yehuda Katz撰写的博客文章非常清晰地解释了JavaScript中的“this”。 - Henrik N

9
最简单的解释,就是我觉得如下所述:

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

试一下这个

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接