JS中關(guān)于事件處理函數(shù)名后面是否帶括號(hào)的問題
今天總結(jié)一個(gè)關(guān)于事件處理程序的小細(xì)節(jié)。首先回顧一下事件處理的一些概念。
JS中的事件處理(事件綁定)就是讓某種或某些事件觸發(fā)某些活動(dòng)。有兩種常見的形式,分別是DOM Level 0 和DOM Level 2。這兩種方式最大的區(qū)別就在于DOM 0級(jí)事件處理只能用于事件冒泡,而DOM 2級(jí)事件處理卻可以通過設(shè)置第三個(gè)參數(shù)來分別支持事件冒泡和事件捕獲。
DOM 0級(jí)事件處理一般是直接把一個(gè)函數(shù)分配給一個(gè)事件處理程序,既可以在元素中直接分配一個(gè)事件處理程序,如方式一所示;也可以在腳本中把函數(shù)分配給事件處理程序,如方式二所示。
<!--方式一--> <div onclick="fun1();fun2('world!');"></div> <!--方式二--> <div id="a">點(diǎn)我</div> <script> var a=document.getElementById("a"); a.onclick=fun1; //方式二 function fun1(){ alert("hello!"); } function fun2(cc){ alert(cc); } </script>
這兩種方式的區(qū)別在上述示例中也顯示了,第一種方式可以同時(shí)綁定多個(gè)處理函數(shù),但要注意必須是全局函數(shù),否則會(huì)拋出Reference錯(cuò)誤。第二種方式只能一次綁定一個(gè)處理函數(shù),否則新的函數(shù)會(huì)覆蓋舊的函數(shù)。
DOM 2級(jí)事件處理不會(huì)直接綁定處理函數(shù),而是將函數(shù)添加為一個(gè)事件監(jiān)聽器如下,他也可以綁定多個(gè)處理函數(shù),不會(huì)產(chǎn)生覆蓋。但這種方式存在瀏覽器兼容的問題,IE下必須用attachEvent方法代替。
a.addEventListener("click",fun1,false); //事件冒泡 a.addEventListener("click",anotherFun,false); //不會(huì)覆蓋上一事件,均被執(zhí)行
簡單回顧到這里,言歸正傳,不知道在回顧的過程中大家有沒有注意到一個(gè)令人困惑的小細(xì)節(jié),就是引用函數(shù)的時(shí)候,函數(shù)名稱后面有的時(shí)候加括號(hào),有的時(shí)候不加括號(hào)。這到底對(duì)程序的運(yùn)行有怎樣的影響呢?我經(jīng)過查閱資料按照自己的理解小小的總結(jié)如下。
首先是加括號(hào)的,你可能經(jīng)常在程序里面這樣寫“fun1();”,沒錯(cuò),函數(shù)名后邊加括號(hào)表示立即執(zhí)行該函數(shù),如果函數(shù)內(nèi)存在返回值則得到該值。這樣用的多了,你可能就習(xí)慣在所有調(diào)用函數(shù)的地方這樣寫,比如之前說的事件處理函數(shù)。但是,如果你這樣做了那就可能造成一些失控的狀況。比如說,你明明只是想在點(diǎn)擊某一元素的時(shí)候才執(zhí)行函數(shù),卻發(fā)現(xiàn)這個(gè)函數(shù)在一開始就被執(zhí)行了。你可以發(fā)現(xiàn),上面舉例時(shí)所用的DOM0方式二和DOM2級(jí)事件處理函數(shù)都沒有在函數(shù)名后面加括號(hào),原因就在于避免這種狀況發(fā)生。如果你加了括號(hào),這個(gè)函數(shù)fun1就會(huì)被立即觸發(fā)執(zhí)行。
那為什么DOM0方式一中卻有括號(hào)呢?那是因?yàn)闃?biāo)簽的事件屬性里引號(hào)之間會(huì)被當(dāng)做js語句直接執(zhí)行,加了括號(hào)才能保證調(diào)用并執(zhí)行函數(shù)。但是由于是用元素標(biāo)簽這種方式綁定的事件,執(zhí)行的時(shí)機(jī)就被控制在了點(diǎn)擊該標(biāo)簽時(shí)觸發(fā)。
如果沒有函數(shù)名又想立即執(zhí)行呢?也就是立即執(zhí)行匿名函數(shù)表達(dá)式,這種模式很常見,來觀察一下它的屁股后面是不是也跟著個(gè)立即執(zhí)行小括號(hào)呢?注意,這種IIFE形式中包裹著整個(gè)函數(shù)體的小括號(hào)會(huì)限制作用域。具體對(duì)IIFE感興趣的童鞋可以去查閱相關(guān)資料,這里不作贅述。
(function(){ //do something... })();
現(xiàn)在再來分析不加括號(hào)的,前面我們提到了不加括號(hào)可以避免失控。是因?yàn)橹粚⒑瘮?shù)名傳遞給事件,相當(dāng)于將函數(shù)指針(也就是這個(gè)函數(shù)的入口地址)傳給元素事件。這樣做的好處就在于可以在需要的時(shí)候找到函數(shù)并執(zhí)行。打個(gè)小比喻來說,你和你的朋友會(huì)面,加了小括號(hào)時(shí)你的朋友就立即出現(xiàn)在你面前,他才不管你當(dāng)時(shí)是不是在忙,有種不請(qǐng)自來的不快感;而不加括號(hào)相當(dāng)于你的朋友告訴了你他家在哪,當(dāng)你需要他的時(shí)候就來找他,這可真是位貼心的朋友啦。所以,大多數(shù)事件綁定都僅僅只是傳遞給事件一個(gè)函數(shù)指針也就是函數(shù)名。
這時(shí)又有一個(gè)問題,之前說明的都是無參函數(shù),如果是像代碼示例中的fun2這種有參函數(shù)怎么辦呢?難道只能用DOM0的方式一那種方法么?當(dāng)然是否定的,盡量不要使用DOM0方式一那種形式,不符合結(jié)構(gòu)與行為分離的原則。一般這種情況下就是使用匿名函數(shù)解決了,如下代碼所示。如果大家有什么好的建議也可以留言分享一下~
//DOM Level 0 a.onclick=function(){ fun2("world!"); }; //DOM Level 2 a.addEventListener("click",function(){fun2("world!");},false);
以上就是我的總結(jié),如有錯(cuò)誤還要請(qǐng)大家多多指正,謝謝!感謝一起學(xué)習(xí)的小伙伴陳童鞋,正是因?yàn)樗岬膯栴}才讓我注意到了這個(gè)經(jīng)常被忽略的細(xì)節(jié)。
以上所述是小編給大家介紹的JS中關(guān)于事件處理函數(shù)名后面是否帶括號(hào)的問題,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- javascript時(shí)間函數(shù)基礎(chǔ)介紹
- JavaScript常用正則驗(yàn)證函數(shù)實(shí)例小結(jié)【年齡,數(shù)字,Email,手機(jī),URL,日期等】
- 深入理解javascript函數(shù)參數(shù)與閉包
- AngularJS中一般函數(shù)參數(shù)傳遞用法分析
- js調(diào)用父框架函數(shù)與彈窗調(diào)用父頁面函數(shù)的簡單方法
- JS中跨頁面調(diào)用變量和函數(shù)的方法(例如a.js 和 b.js中互相調(diào)用)
- 在html中引入外部js文件,并調(diào)用帶參函數(shù)的方法
- 淺析JS中對(duì)函數(shù)function的理解(基礎(chǔ)篇)
- Vuejs第一篇之入門教程詳解(單向綁定、雙向綁定、列表渲染、響應(yīng)函數(shù))
- Javascript日期格式化format函數(shù)的使用方法
- JavaScript中函數(shù)聲明與函數(shù)表達(dá)式的區(qū)別詳解
- JavaScript函數(shù)基礎(chǔ)詳解
- 解決同一頁面中兩個(gè)iframe互相調(diào)用jquery,js函數(shù)的方法
相關(guān)文章
用html5 js實(shí)現(xiàn)點(diǎn)擊一個(gè)按鈕達(dá)到瀏覽器全屏效果
點(diǎn)擊一個(gè)按鈕要實(shí)現(xiàn)按F11全屏的效果。 在HTML5中,W3C制定了關(guān)于全屏的API,就可以實(shí)現(xiàn)全屏幕的效果2014-05-05echarts實(shí)現(xiàn)晶體球面投影的實(shí)例教程
這篇文章主要給大家介紹了關(guān)于echarts實(shí)現(xiàn)晶體球面投影的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10JavaScript實(shí)現(xiàn)簡易放大鏡最全代碼解析(ES5)
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡易放大鏡最全代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09獲取JS中網(wǎng)頁各種高寬與位置的方法總結(jié)
本文詳細(xì)羅列了如何在javascript獲取網(wǎng)頁各種高寬及位置,內(nèi)容比較全面,有需要的可以參考一下。2016-07-07bootstrap modal+gridview實(shí)現(xiàn)彈出框效果
這篇文章主要介紹了bootstrap modal+gridview實(shí)現(xiàn)彈出框效果,gridview點(diǎn)擊更新彈出填寫信息表單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08uniapp項(xiàng)目實(shí)踐封裝通用請(qǐng)求上傳以及下載方法總結(jié)
在日常開發(fā)過程中,前端經(jīng)常要和后端進(jìn)行接口聯(lián)調(diào),獲取并且渲染數(shù)據(jù)到頁面中,接下來就總結(jié)一下?uniapp?中獲取請(qǐng)求、文件下載和上傳的一些方法2023-09-09html a標(biāo)簽-超鏈接中confirm方法使用介紹
confirm可以彈出確定取消對(duì)話框,然后根據(jù)用戶的選擇執(zhí)行相應(yīng)的操作,接下來介紹實(shí)現(xiàn)過程,需要了解的朋友可以參考下2013-01-01