JavaScript 匿名立即自執行函式
匿名自執行函式在當前應用非常廣泛,通過它可以避免很多程式設計中常見問題。
下面將通過程式碼例項對其進行詳細介紹,文字主要涵蓋如下幾個方面內容:
(1).什麼是匿名立即自執行函式。
(2).匿名函式的主要應用方式。
一.匿名立即自執行函式:
匿名立即自執行函式是一種函式應用方式,可以使匿名函式建立之後立即執行。
它並不是ES中定義的一個標準術語,只是對此種應用方式的一種貼切的描述。
建立函式的方式有兩種,一種是函式宣告方式,一種是函式表示式方式。
本文對於函式的建立不做過多介紹,具體參閱JavaScript function 函式一章節。
函式宣告方式建立的函式必定是具名函式,表示式方式建立的函式可以是匿名函式,也可以是具名函式。
程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼// 具名函式 let funcJ = function f() {} // 匿名函式 let funcN = function() {}
不要想當然認為funcN是函式的名稱,只是一個變數而已,變數值是一個匿名函式。
既然要執行,自然要呼叫匿名函式,程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼執行程式碼(function(){ console.log("螞蟻部落"); })()
上面程式碼會立即列印出字串"螞蟻部落",但是上述方式並推薦使用,程式碼修改如下:
[JavaScript] 純文字檢視 複製程式碼執行程式碼(function(){ console.log("螞蟻部落"); }())
呼叫匿名函式的小括號應該在小括號之內。
雖然第一種寫法在語法上完全沒有問題,但是第二種寫法看起來更像一個整體。
再額外介紹一個知識點,標準規定,凡是function關鍵字出現在程式碼的行首,那麼程式碼畢竟被解讀為語句。
表示式返回一個值,但是語句並不能,所以如下方式呼叫函式是錯誤的:
[JavaScript] 純文字檢視 複製程式碼function func(){}()
但是我們可以先轉換為一個表示式,然後再呼叫,程式碼例項如下:
[JavaScript] 純文字檢視 複製程式碼(function func(){})()
將函式放入小括號後,形成一個表示式,表示式能夠返回一個值,也就是函式物件。
二.匿名函式主要應用方式:
(1).避免作用域命名汙染:
函式可以生成一個函式作用域,全域性作用域變數和此函式作用域中的同名變數不會產生汙染。
這個一點非常容易理解,看如下程式碼例項:
[JavaScript] 純文字檢視 複製程式碼執行程式碼let webName="百度"; (function(){ let webName="螞蟻部落"; console.log(webName); }()) console.log(webName);
程式碼執行效果截圖如下:
再來看一個常見的應用,比如頁面要引入兩個檔案a.js與b.js,這兩個檔案中,都宣告瞭變數webName。
那麼同時引入的時候,就可能會產生衝突導致問題,比如後面的變數覆蓋前面的,只要將各自檔案的js程式碼放入匿名自執行函式即可解決此問題,程式碼如下:
[JavaScript] 純文字檢視 複製程式碼// a.js (function() { var webName = "螞蟻部落"; })(); // b.js (function() { var webName = "百度"; })();
(2).提升效能:
這一點可能很多朋友不是太理解,下面進行一下演示。
[JavaScript] 純文字檢視 複製程式碼(function(){ // code }(window))
上述程式碼為匿名函式傳遞引數window,如果匿名函式內有對window物件的引用,在一定程度上可以提升效能。
因為不用越過函式作用域向上級作用域查詢window物件,減少了對作用域的查詢操作。
(3).儲存閉包狀態:
首先看一段程式碼例項,如果不注意可能出現意想不到的問題,尤其會給新手帶來不小的困擾。
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <style> ul li{ width:300px; list-style-type:none; font-size:12px; line-height:30px; height:30px; cursor:pointer; } ul li span{ float:right } </style> <script> window.onload=function(){ var obox=document.getElementById("box"); var lis=obox.getElementsByTagName("li"); var odiv=document.getElementById("show"); for(var index=0;index<lis.length;index++){ lis[index].onclick= function(){ odiv.innerHTML=index; } } } </script> </head> <body> <ul id="box"> <li>螞蟻部落一</li> <li>螞蟻部落二</li> <li>螞蟻部落三</li> <li>螞蟻部落四</li> <li>螞蟻部落五</li> </ul> <div id="show"></div> </body> </html>
上述程式碼的初衷是,點選li元素可以將對應元素的索引位置寫入div中。
但是結果卻並非如此,點選任何一個li元素,在div中顯示的數字都是5,好像邏輯上沒有任何問題。
原因是這樣的,當通過for迴圈為li元素註冊事件處理函式,index的值也隨之增加,當for迴圈結束之後,index的值到達5,點選li元素是for迴圈結束之後的事情,所以index值已經變成了5,本質原因是index的作用域是load事件處理函式。下面通過匿名函式修改如下:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <style> ul li{ width:300px; list-style-type:none; font-size:12px; line-height:30px; height:30px; cursor:pointer; } ul li span{ float:right } </style> <script> window.onload=function(){ var obox=document.getElementById("box"); var lis=obox.getElementsByTagName("li"); var odiv=document.getElementById("show"); for(var index=0;index<lis.length;index++){ lis[index].onclick=(function(index){ return function(){ odiv.innerHTML=index; } })(index) } } </script> </head> <body> <ul id="box"> <li>螞蟻部落一</li> <li>螞蟻部落二</li> <li>螞蟻部落三</li> <li>螞蟻部落四</li> <li>螞蟻部落五</li> </ul> <div id="show"></div> </body> </html>
上面程式碼將index作為匿名函式的引數,這樣index的作用域被封閉在獨立的匿名函式中,相互不會影響。ES2015提供了塊級作用域,現在看來上述方式就有點多餘(不考慮瀏覽器相容性問題的話),程式碼例項如下:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <style> ul li{ width:300px; list-style-type:none; font-size:12px; line-height:30px; height:30px; cursor:pointer; } ul li span{ float:right } </style> <script> window.onload=function(){ var obox=document.getElementById("box"); var lis=obox.getElementsByTagName("li"); var odiv=document.getElementById("show"); for(let index=0;index<lis.length;index++){ lis[index].onclick= function(){ odiv.innerHTML=index; } } } </script> </head> <body> <ul id="box"> <li>螞蟻部落一</li> <li>螞蟻部落二</li> <li>螞蟻部落三</li> <li>螞蟻部落四</li> <li>螞蟻部落五</li> </ul> <div id="show"></div> </body> </html>
只要將var修改成let即可,那麼{}就可以形成一個塊級作用域,var宣告變數不具備此功能。
關於let與塊級作用域可以參閱如下兩篇文章:
(1).JavaScript let 命令一章節。
(2).JavaScript 塊級作用域一章節。
相關文章
- 塊級作用域替代“匿名立即執行函式表示式(匿名IIFE)”函式
- 深入理解 函式、匿名函式、自執行匿名函式函式
- 立即執行函式函式
- JavaScript 立即執行函式、逗號運算JavaScript函式
- JavaScript 匿名函式與具名函式執行效率比較JavaScript函式
- js立即執行函式原理JS函式
- 03-立即執行函式函式
- 胡扯JS系列-匿名函式的自動執行JS函式
- JavaScript 匿名函式JavaScript函式
- 立即執行函式(IIFE)&&閉包函式
- JS小知識——立即執行函式JS函式
- 自執行函式函式
- 由兩道題擴充套件的對作用域,作用域鏈,閉包,立即執行函式,匿名函式的認識總結套件函式
- 【譯】JavaScript 模組:從立即執行函式 ( IIFEs ) 到 CommonJS 再到 ES6 模組JavaScript函式JS
- 學習javaScript必知必會(1)~js介紹、函式、匿名函式、自呼叫函式、不定長引數JavaScriptJS函式
- 立即執行函式在前端國際化方案中的應用函式前端
- 舉例說明js立即執行函式的寫法有哪些?JS函式
- Golang匿名函式Golang函式
- Ruby 匿名函式函式
- PHP匿名函式PHP函式
- Go 匿名函式Go函式
- 匿名函式(Python)函式Python
- JavaScript匿名函式要外面巢狀小括號原因JavaScript函式巢狀
- 1.5.7 Python匿名函式Python函式
- PHP 匿名函式初探PHP函式
- Python函式與lambda 表示式(匿名函式)Python函式
- 閉包函式(匿名函式)的理解函式
- 第 8 節:函式-匿名函式、遞迴函式函式遞迴
- Python 返回函式+匿名函式Python函式
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- JavaScript: window.onload = function() {} 裡面的函式不執行JavaScriptFunction函式
- 兄弟連go教程(14)函式 - 匿名函式Go函式
- js中自執行函式的怪異行為研究JS函式
- 裝飾器,匿名函式函式
- PHP 核心特性 - 匿名函式PHP函式
- js中的匿名函式JS函式
- 初識Lambda表示式(匿名函式)函式
- 從settTimeout到匿名函式、箭頭函式之() => {}函式