js中關於事件處理函數名後面是否帶括弧的問題

来源:http://www.cnblogs.com/sammiyu/archive/2016/11/16/my_tech3.html
-Advertisement-
Play Games

JS中的事件處理(事件綁定)就是讓某種或某些事件觸發某些活動。有兩種常見的形式,分別是DOM Level 0 和DOM Level 2。這兩種方式最大的區別就在於DOM 0級事件處理只能用於事件冒泡,而DOM 2級事件處理卻可以通過設置第三個參數來分別支持事件冒泡和事件捕獲。 DOM 0級事件處理一 ...


  今天總結一個關於事件處理程式的小細節。首先回顧一下事件處理的一些概念。

  JS中的事件處理(事件綁定)就是讓某種或某些事件觸發某些活動。有兩種常見的形式,分別是DOM Level 0 和DOM Level 2。這兩種方式最大的區別就在於DOM 0級事件處理只能用於事件冒泡,而DOM 2級事件處理卻可以通過設置第三個參數來分別支持事件冒泡和事件捕獲。

  DOM 0級事件處理一般是直接把一個函數分配給一個事件處理程式,既可以在元素中直接分配一個事件處理程式,如方式一所示;也可以在腳本中把函數分配給事件處理程式,如方式二所示。

<!--方式一-->
<div onclick="fun1();fun2('world!');"></div>

<!--方式二-->
<div id="a">點我</div>

<script>
    var a=document.getElementById("a");

    a.onclick=fun1;   //方式二 

    function fun1(){
        alert("hello!");
    }

    function fun2(cc){
        alert(cc);
    }
</script>

  這兩種方式的區別在上述示例中也顯示了,第一種方式可以同時綁定多個處理函數,但要註意必須是全局函數,否則會拋出Reference錯誤。第二種方式只能一次綁定一個處理函數,否則新的函數會覆蓋舊的函數。

  DOM 2級事件處理不會直接綁定處理函數,而是將函數添加為一個事件監聽器如下,他也可以綁定多個處理函數,不會產生覆蓋。但這種方式存在瀏覽器相容的問題,IE下必須用attachEvent方法代替。

a.addEventListener("click",fun1,false); //事件冒泡
a.addEventListener("click",anotherFun,false); //不會覆蓋上一事件,均被執行

  簡單回顧到這裡,言歸正傳,不知道在回顧的過程中大家有沒有註意到一個令人困惑的小細節,就是引用函數的時候,函數名稱後面有的時候加括弧,有的時候不加括弧。這到底對程式的運行有怎樣的影響呢?我經過查閱資料按照自己的理解小小的總結如下。

  首先是加括弧的,你可能經常在程式裡面這樣寫“fun1();”,沒錯,函數名後邊加括弧表示立即執行該函數,如果函數記憶體在返回值則得到該值。這樣用的多了,你可能就習慣在所有調用函數的地方這樣寫,比如之前說的事件處理函數。但是,如果你這樣做了那就可能造成一些失控的狀況。比如說,你明明只是想在點擊某一元素的時候才執行函數,卻發現這個函數在一開始就被執行了。你可以發現,上面舉例時所用的DOM0方式二和DOM2級事件處理函數都沒有在函數名後面加括弧,原因就在於避免這種狀況發生。如果你加了括弧,這個函數fun1就會被立即觸發執行。

  那為什麼DOM0方式一中卻有括弧呢?那是因為標簽的事件屬性里引號之間會被當做js語句直接執行,加了括弧才能保證調用並執行函數。但是由於是用元素標簽這種方式綁定的事件,執行的時機就被控制在了點擊該標簽時觸發。

  如果沒有函數名又想立即執行呢?也就是立即執行匿名函數表達式,這種模式很常見,來觀察一下它的屁股後面是不是也跟著個立即執行小括弧呢?註意,這種IIFE形式中包裹著整個函數體的小括弧會限製作用域。具體對IIFE感興趣的童鞋可以去查閱相關資料,這裡不作贅述。

(function(){
    //do something...
})();

  現在再來分析不加括弧的,前面我們提到了不加括弧可以避免失控。是因為只將函數名傳遞給事件,相當於將函數指針(也就是這個函數的入口地址)傳給元素事件。這樣做的好處就在於可以在需要的時候找到函數並執行。打個小比喻來說,你和你的朋友會面,加了小括弧時你的朋友就立即出現在你面前,他才不管你當時是不是在忙,有種不請自來的不快感;而不加括弧相當於你的朋友告訴了你他家在哪,當你需要他的時候就來找他,這可真是位貼心的朋友啦。所以,大多數事件綁定都僅僅只是傳遞給事件一個函數指針也就是函數名。

  這時又有一個問題,之前說明的都是無參函數,如果是像代碼示例中的fun2這種有參函數怎麼辦呢?難道只能用DOM0的方式一那種方法麽?當然是否定的,儘量不要使用DOM0方式一那種形式,不符合結構與行為分離的原則。一般這種情況下就是使用匿名函數解決了,如下代碼所示。如果大家有什麼好的建議也可以留言分享一下~

//DOM Level 0
a.onclick=function(){
    fun2("world!");
};

//DOM Level 2
a.addEventListener("click",function(){fun2("world!");},false);

  以上就是我的總結,如有錯誤還要請大家多多指正,謝謝!感謝一起學習的小伙伴陳童鞋,正是因為他提的問題才讓我註意到了這個經常被忽略的細節。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前端學習還是很有趣的,可以較快的上手然後自己開發一些好玩的項目來練手,網上也可以一抓一大把關於前端開發的小項目,可是還是有新手在學習的時候不知道可以做什麼,以及怎麼做,因此, "實驗樓" 就整理了一些前端項目教程,希望可以幫助正在學習前端的小伙伴。 為了方便閱讀,大概把前端可以做的項目分為三類: 游 ...
  • 據我對cookie誕生背景的瞭解,cookie是由網景公司創建的,目的就是將用戶的數據儲存在客戶端上。伴隨的HTML5的出現,現在又有另外一個解決數據離線儲存的方案,就是HTML5中的Web storage,其中兩個重要對象sessionStorage和localStorage可以解決瀏覽器sess ...
  • 前言:之前自學了一些關於CSS3的知識,在學習過程中也遇到過坑,不過總算磕磕絆絆的學習完了關於CSS3的相關知識,於是最近把之前的筆記和代碼整理了一下,也算是一個對CSS3知識的回顧複習吧,也希望能夠對想學這方面知識的小白有所幫助。因為是各種渠道找的資料,學習的不算系統,所以知識點涵蓋的不甚全面,望 ...
  • placeholder:占位符。 ...
  • 轉自:http://blog.sina.com.cn/s/blog_6d63cf160102vbsg.html 只需要加入 ...
  • 只需在jquery.validate.js 文件中在446行附近找到return $([]).add(this.currentForm.elements).filter(":input")更換成 ...
  • 1、實現方法 2、註意的問題 1、實現方法 利用css分欄,一個整體的div id為wrap ,包含三個div,分別代表左欄(wrap-1)、中欄(wrap-m)、右欄(wrap-r) 通過float屬性使wrap-1 位於左邊,wrap-r位於右邊,再通過margin屬性進一步完善邊框的距離,添加 ...
  • 微信 小程式 drawImage wx.canvasToTempFilePath wx.saveFile 獲取設備寬高 尺寸問題 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...