ต้องการคำอธิบายของฟังก์ชัน _.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
คำอธิบายดีๆ
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>

น่าเสียดายที่ฟังก์ชัน "ผูกทั้งหมด" ที่แท้จริงจะใช้ได้เฉพาะกับฟังก์ชันที่อยู่บนวัตถุเท่านั้น จะรวมถึงฟังก์ชั่นที่มีการกำหนดไว้ในต้นแบบที่คุณต้องผ่านชื่อฟังก์ชันเหล่านั้น explicitely _.bindAll()เป็นอาร์กิวเมนต์เพิ่มเติมเพื่อ

อย่างไรก็ตามคุณต้องการคำอธิบาย: โดยทั่วไปจะช่วยให้คุณสามารถแทนที่ฟังก์ชันบนวัตถุด้วยฟังก์ชันที่มีชื่อและลักษณะการทำงานเหมือนกัน แต่ยังผูกไว้กับวัตถุนั้นด้วยดังนั้นthis === theObjectแม้จะไม่เรียกมันว่าเป็นวิธีการ ( theObject.method())


@ThiefMaster "ส่งชื่อฟังก์ชันเหล่านั้นอย่างชัดเจนเป็นอาร์กิวเมนต์เพิ่มเติมไปยัง _.bindAll ()" ขออภัยยังคงเรียนรู้จากตัวอย่างของคุณและพยายามหาผลกระทบที่นี่: ดังนั้นคุณจึงบอกว่าฟังก์ชันที่กำหนดบนต้นแบบไม่ได้ถูกผูกไว้โดยอัตโนมัติกับวัตถุภายใต้ _.bindAll และถ้าจะให้บรรลุสิ่งนี้ต้องป้อน พารามิเตอร์แรกกับวัตถุ พารามิเตอร์ตัวที่สองชื่อฟังก์ชั่นถ้าฟังก์ชันนั้นถูกกำหนดบนต้นแบบ?
Nik So

9
โพสต์บล็อกนี้โดย Yehuda Katzอธิบาย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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.