потрібне пояснення функції _.bindAll () від Underscore.js


85

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

_.bindAll(object, [*methodNames]) 

Зв'язує ряд методів на об'єкті, зазначених у methodNames, для запуску в контексті цього об'єкта щоразу, коли вони викликаються. Дуже зручно для функцій прив'язки, які будуть використовуватися як обробники подій, які в іншому випадку будуть викликані з досить марним цим. Якщо не вказано 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...

Якщо ви можете допомогти тут, подавши ще один приклад, можливо, або якесь словесне пояснення, все буде вдячне. Я намагався шукати більше підручників чи прикладів, але нічого не виявилося, що обслуговує те, що мені потрібно. Здається, більшість людей просто знають, що це робить автоматично ...


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 "передає ці імена функцій явно як додаткові аргументи _.bindAll ()." Вибачте, але все ще вчимось на вашому прикладі і намагаємось з’ясувати його наслідки тут: отже, ви говорите, що функції, визначені в прототипі, не будуть автоматично пов’язані з об’єктом під _.bindAll, і якщо хтось цього хоче досягти, потрібно подати перший параметр з об'єктом; другий параметр ім'я функції, якщо ця функція була визначена на прототипі?
Nik So

9
Цей допис у блозі Єгуди Кацthis дуже добре пояснює на JavaScript.
Генрік Н

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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.