требуется объяснение функции _.bindAll () из Underscore.js

85

Я изучал backbone.js и видел множество случаев, когда _.bindAll()он используется. Я прочитал всю страницу документации backbone.js и underscore.js, чтобы попытаться понять, что он делает, но я все еще очень не уверен в том, что он делает. Вот объяснение подчеркивания:

_.bindAll(object, [*methodNames]) 

Привязывает ряд методов к объекту, указанному в methodNames, для запуска в контексте этого объекта при каждом их вызове. Очень удобно для связывания функций, которые будут использоваться в качестве обработчиков событий, которые в противном случае вызывались бы с довольно бесполезным this. Если имя метода не указано, все свойства функции объекта будут привязаны к нему.

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
Отличное объяснение: blog.bigbinary.com/2011/08/18/…
jared_flack

Ответы:

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
источник
@ThiefMaster «явно передает эти имена функций в качестве дополнительных аргументов в _.bindAll ()». Извините, я все еще учусь на вашем примере и пытаюсь понять его последствия здесь: вы говорите, что функции, определенные в прототипе, не связываются автоматически с объектом в _.bindAll, и если бы кто-то должен был достичь этого, нужно скормить первый параметр с объектом; второй параметр имя функции ЕСЛИ эта функция была определена в прототипе?
Nik So
9
Это сообщение в блоге Иегуды Кацаthis очень хорошо объясняет на JavaScript.
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>
дикий горох
источник