需要来自Underscore.js的_.bindAll()函数的解释


85

我一直在学习一些ribs.js,并且已经看到很多使用实例_.bindAll()。我已经通读了整张骨架.js和underscore.js文档页面,以试图了解它的功能,但是对于它的功能我仍然很模糊。这是下划线的说明:

_.bindAll(object, [*methodNames]) 

在方法名称上指定的对象上绑定许多方法,以便在调用它们时在该对象的上下文中运行。对于将用作事件处理程序的绑定函数非常方便,否则将使用相当无用的this来调用它们。如果未提供methodNames,则该对象的所有函数属性都将绑定到它。

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

如果您可以在此举另一个例子或一些口头解释来帮助您,那么您将不胜感激。我尝试搜索更多的教程或示例,但没有找到可以满足我需要的内容。大多数人似乎只知道它会自动执行...


Answers:


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>

不幸的是,实际的“全部绑定”功能仅适用于对象上的功能。要包括在原型上定义的功能,您需要将这些功能名称明确地传递为的附加参数_.bindAll()

无论如何,您都需要一个解释:基本上,它允许您用具有相同名称和行为的函数替换对象上的函数,但该函数也已绑定到该对象,因此this === theObject即使不将其作为方法(theObject.method())调用也是如此。


@ThiefMaster“将这些函数名称显式传递为_.bindAll()的附加参数。” 抱歉,仍然从您的示例中学习并尝试在这里找出其含义:因此,您说在原型上定义的函数不会自动与_.bindAll下的对象绑定,如果要实现此功能,则需要将其提供给对象的第一个参数;第二个参数是函数名称,如果函数是在原型上定义的?
Nik So

9
Yehuda Katz的这篇博客文章this很好地解释了JavaScript。
亨里克·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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.