.bind()之美
我并不是 Prototype JavaScript framework 的忠實(shí)粉絲,但我對(duì)它的總體代碼質(zhì)量印象深刻。具體而言,它為Function對(duì)象增加一個(gè)簡(jiǎn)潔的補(bǔ)充,對(duì)我管理函數(shù)呼叫執(zhí)行后的上下文產(chǎn)生了極大的正面影響:bind跟call一樣執(zhí)行相同的常見(jiàn)任務(wù),改變函數(shù)執(zhí)行的上下文。不同之處在于bind返回的是函數(shù)引用可以備用,而不是call的立即執(zhí)行而產(chǎn)生的最終結(jié)果。
如果需要簡(jiǎn)化一下bind函數(shù)以抓住概念的重點(diǎn),我們可以先把它插進(jìn)前面討論的乘積例子中去,看它究竟是如何工作的。這是一個(gè)相當(dāng)優(yōu)雅的解決方案:
<script type="text/javascript"> var first_object = { num: 42 }; var second_object = { num: 24 };
function multiply(mult) { return this.num * mult; }
Function.prototype.bind = function(obj) { var method = this, temp = function() { return method.apply(obj, arguments); };
return temp; }
var first_multiply = multiply.bind(first_object); first_multiply(5); // 返回 42 * 5
var second_multiply = multiply.bind(second_object); second_multiply(5); // 返回 24 * 5 </script>
首先,我們定義了first_object, second_object和multiply函數(shù),一如既往。細(xì)心處理這些后,我們繼續(xù)為Function對(duì)象的 prototype 定義一個(gè)bind方法,這樣的話,我們程序里的函數(shù)都有一個(gè)bind方法可用。當(dāng)執(zhí)行multiply.bind(first_object)時(shí),JavaScript為bind方法創(chuàng)建一個(gè)運(yùn)行上下文,把this置為multiply函數(shù)的引用,并把第一個(gè)參數(shù)obj置為first_object的引用。目前為止,一切皆順。
這個(gè)解決方案的真正天才之處在于method的創(chuàng)建,置為this的引用所指(即multiply函數(shù)自身)。當(dāng)下一行的匿名函數(shù)被創(chuàng)建,method通過(guò)它的作用域鏈訪問(wèn),obj亦然(不要在此使用this, 因?yàn)樾聞?chuàng)建的函數(shù)執(zhí)行后,this會(huì)被新的、局部的上下文覆蓋)。這個(gè)this的別名讓apply執(zhí)行multiply函數(shù)成為可能,而傳遞obj則確保上下文的正確。用計(jì)算機(jī)科學(xué)的話說(shuō),temp是一個(gè) 閉包(closure),它可以保證,需要在first_object的上下文中執(zhí)行multiply,bind呼叫的最終返回可以用在任何的上下文中。
這才是前面說(shuō)到的事件處理函數(shù)和setTimeout情形所真正需要的。以下代碼完全解決了這些問(wèn)題,綁定deep_thought.ask_question方法到deep_thought的上下文中,因此能在任何事件觸發(fā)時(shí)都能正確運(yùn)行:
function addhandler() { var deep_thought = new BigComputer(42), the_button = document.getElementById('thebutton');
the_button.onclick = deep_thought.ask_question.bind(deep_thought); }
漂亮。
本文鏈接:http://m.95time.cn/tech/web/2007/4855.asp
出處:Realazy
責(zé)任編輯:moby
上一頁(yè) JavaScript 中的作用域 [3] 下一頁(yè)
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|