js的(function(){xxx})()使用詳解
這次帶給大家js的(function(){xxx})()使用詳解,js的(function(){xxx})()使用的注意事項有哪些,下面就是實戰案例,一起來看一下。
js中(function(){xxx})();寫法解析
自執行匿名函數:
常見格式:(function() { /* code */ })();
解釋:包圍函數(function(){})的第一對括號向腳本傳回未命名的函數,隨後一對空括號立即執行傳回的未命名函數,括號內為匿名函數的參數。
作用:可以用它來建立命名空間,只要把自己所有的程式碼都寫在這個特殊的函式包裝內,那麼外部就不能訪問,除非你允許(變數前加上window,這樣函數或變數就成為全域)。各JavaScript函式庫的程式碼也基本上是這種組織形式。
總結一下,執行函數的作用主要為 匿名 和 自動執行,程式碼在解釋時就已經在運作了。
其他寫法
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function () { /* code */ } ()); <br>!function () { /* code */ } ();<br>~function () { /* code */ } ();<br>-function () { /* code */ } ();<br>+function () { /* code */ } ();</span>
function與感嘆號
最近有空可以讓我靜下心來看看各種代碼,function與感嘆號的頻繁出現,讓我回想起2個月前我回杭州最後參加團隊會議的時候,@西子劍影拋出的一樣的問題:如果在function之前加上感嘆號(!) 會怎麼樣?例如下面的程式碼:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>!function(){alert('iifksp')}() // true</span>
在控制台運行後得到的值時true,為什麼是true這很容易理解,因為這個匿名函數沒有回傳值,預設回傳的就是undefined ,求反的結果很自然的就是true。所以問題不在於結果值,而是在於,為什麼求反操作能夠讓一個匿名函數的自調變的合法性?
平時我們可能會對新增括號來呼叫匿名函數的方式更為習慣:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')})() // true</span>
或:##
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')}()) // true</span>
雖然上述兩者括號的位置不同,不過效果完全一樣。
那麼,是什麼好處使得為數不少的人對這種嘆號的方式情有獨鍾?如果只是為了節省一個字元未免太沒有必要了,這樣算來即使一個100K的庫恐怕也節省不了多少空間。既然不是空間,就是說也許還有時間上的考量,事實很難說清,文章的最後有提到性能。
回到核心問題,為什麼可以這麼做?甚至更核心的問題是,為什麼必須這麼做?
其實無論是括號,或是感嘆號,讓整個語句合法做的事情只有一件,就是讓一個函數宣告語句變成了一個表達式。
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>function a(){alert('iifksp')} // undefined</span>
这是一个函数声明,如果在这么一个声明后直接加上括号调用,解析器自然不会理解而报错:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>function a(){alert('iifksp')}() // SyntaxError: unexpected_token</span>
因为这样的代码混淆了函数声明和函数调用,以这种方式声明的函数 a,就应该以 a(); 的方式调用。
但是括号则不同,它将一个函数声明转化成了一个表达式,解析器不再以函数声明的方式处理函数a,而是作为一个函数表达式处理,也因此只有在程序执行到函数a时它才能被访问。
所以,任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。比如:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>var i = function(){return 10}(); // undefined 1 && function(){return true}(); // true 1, function(){alert('iifksp')}(); // undefined</span>
赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,这个不是函数声明,它是个函数表达式。并且,对函数一元运算可以算的上是消除歧义最快的方式,感叹号只是其中之一,如果不在乎返回值,这些一元运算都是有效的:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>!function(){alert('iifksp')}() // true+function(){alert('iifksp')}() // NaN-function(){alert('iifksp')}() // NaN~function(){alert('iifksp')}() // -1</span>
甚至下面这些关键字,都能很好的工作:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>void function(){alert('iifksp')}() // undefined new function(){alert('iifksp')}() // Object delete function(){alert('iifksp')}() // true</span>
最后,括号做的事情也是一样的,消除歧义才是它真正的工作,而不是把函数作为一个整体,所以无论括号括在声明上还是把整个函数都括在里面,都是合法的:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')})() // undefined(function(){alert('iifksp')}()) // undefined</span>
说了这么多,实则在说的一些都是最为基础的概念——语句,表达式,表达式语句,这些概念如同指针与指针变量一样容易产生混淆。虽然这种混淆对编程无表征影响,但却是一块绊脚石随时可能因为它而头破血流。
最后讨论下性能。我在jsperf上简单建立了一个测试:http://jsperf.com/js-funcion-expression-speed ,可以用不同浏览器访问,运行测试查看结果。我也同时将结果罗列如下表所示(由于我比较穷,测试配置有点丢人不过那也没办法:奔腾双核1.4G,2G内存,win7企业版):
選項 | #Ops/sec | ||||
---|---|---|---|---|---|
#Chrome 13 | Firefox 6 | IE9 | |||
#Safari 5 | |||||
! | #!function(){;}() | 3,773,196 | 10,975,198 | 572,694 | 2,810,197 |
## 函數(){;}()#########21,553,847## ##########12,135,960#############572,694############1,812,238#################1,812,238##################1,812,238############# # #####-##########-功能(){;}() | 21,553,847 | #12,135,960 | #572,694 | #1,864,155 | |
~ | ~function(){;}() | #3,551,136 | 3,651,652 | 572,694 | 1,876,002 |
(1) | (函數(){;})() | # #3,914,953 | 12,135,960 | 572,694 | |
(函數(){;}()) | 4,075,201 | #12,135,960 | #572,694 | 3,025,608 | |
void | void function(){;}() | 4,030,756 | 12,135,960 | #572,694 | 3,025,608 |
##new | new function(){;}() | 619,606 | 299,100 | 407,104 | 816,903 |
##刪除 | 刪除函數(){;}() | 4,816,225 | #12,135,960 | #572,694 | #2,693,524 |
= | var i = function(){;}() | 4,984,774 | #12,135,960 | 565,982 | 2,602,630 |
&& | #1 && 函數(){;}() | #5,307,200 | 4,393,486 | 572,694 | #2,565,645 |
2,565,645 | ######2,565,645##################2,565,645####### ### #########||############0 ||功能(){;}() | 5,000,000 | #4,406,035 | #572,694 | #2,490,128 |
& | 1 & function(){;}() | 4,918,209 | 12,135,960 | 572,694 | 1,705,551 |
##| | 1 |函數(){;}() | 4,859,802 | ##12,135,960##572,694 | 1,612,372 | |
1 ^ 函數(){;}() | 4,654,916 | #12,135,960 | #572,694 | 1,579,778 | |
, | 1, function(){;}() | #4,878,193 | 12,135,960 | 572,694 | 2,281,186 |
可見不同的方式產生的結果並不相同,而且,差異很大,因瀏覽器而異。
但我們還是可以從中找出很多共通點:new方法永遠最慢——這也是理所當然的。其實它方面很多差距其實不大,但有一點可以肯定的是,感嘆號並非最理想的選擇。反觀傳統的括號,在測試裡表現始終很快,在大多數情況下比感嘆號更快——所以平時我們常用的方式毫無問題,甚至可以說是最優的。加減號在chrome時表現驚人,在其他瀏覽器下也普遍很快,比起感嘆號效果較好。
當然這只是個簡單測試,不能說明問題。但有些結論是有意義的:括號和加減號最優。
但是為什麼這麼多開發者鍾情於感嘆號?我覺得這只是一個習慣問題,它們之間的優劣完全可以忽略。一旦習慣了一種程式碼風格,那麼這種約定會讓程式從混亂變得可讀。如果習慣了感嘆號,我不得不承認,它比括號有更好的可讀性。我不用在閱讀時留意括號的匹配,也不用在寫作時粗心遺忘——
當我也這麼幹然後嚷嚷著這居然又節省了一個字符而沾沾自喜的時候,卻忘了自己倉皇翻出一本卷邊的C語言教科書的窘迫和荒唐......任何人都有忘記的時候,當再撿起來的時候,撿起的就已經不單單是忘掉的東西了。
我相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是js的(function(){xxx})()使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

磁力連結是一種用於下載資源的連結方式,相較於傳統的下載方式更為便利和有效率。使用磁力連結可以透過點對點的方式下載資源,而不需要依賴中介伺服器。本文將介紹磁力連結的使用方法及注意事項。一、什麼是磁力連結磁力連結是一種基於P2P(Peer-to-Peer)協定的下載方式。透過磁力鏈接,使用者可以直接連接到資源的發布者,從而完成資源的共享和下載。與傳統的下載方式相比,磁

mdf檔案和mds檔案怎麼用隨著電腦科技的不斷進步,我們可以透過多種方式來儲存和共享資料。在數位媒體領域,我們經常會遇到一些特殊的文件格式。在這篇文章中,我們將討論一種常見的文件格式—mdf和mds文件,並介紹它們的使用方法。首先,我們需要了解mdf檔案和mds檔案的含義。 mdf是CD/DVD鏡像檔的副檔名,而mds檔則是mdf檔的元資料檔。

CrystalDiskMark是一款適用於硬碟的小型HDD基準測試工具,可快速測量順序和隨機讀取/寫入速度。接下來就讓小編為大家介紹一下CrystalDiskMark,以及crystaldiskmark如何使用吧~一、CrystalDiskMark介紹CrystalDiskMark是一款廣泛使用的磁碟效能測試工具,用於評估機械硬碟和固態硬碟(SSD)的讀取和寫入速度和隨機I/O性能。它是一款免費的Windows應用程序,並提供用戶友好的介面和各種測試模式來評估硬碟效能的不同方面,並被廣泛用於硬體評

foobar2000是一款能隨時收聽音樂資源的軟體,各種音樂無損音質帶給你,增強版本的音樂播放器,讓你得到更全更舒適的音樂體驗,它的設計理念是將電腦端的高級音頻播放器移植到手機上,提供更便捷高效的音樂播放體驗,介面設計簡潔明了易於使用它採用了極簡的設計風格,沒有過多的裝飾和繁瑣的操作能夠快速上手,同時還支持多種皮膚和主題,根據自己的喜好進行個性化設置,打造專屬的音樂播放器支援多種音訊格式的播放,它還支援音訊增益功能根據自己的聽力情況調整音量大小,避免過大的音量對聽力造成損害。接下來就讓小編為大

輕鬆上手:如何使用pip鏡像來源隨著Python在全球的普及,pip成為了Python套件管理的標準工具。然而,許多開發者在使用pip安裝套件時面臨的常見問題是速度慢。這是因為預設情況下,pip從Python官方來源或其他外部來源下載包,而這些來源可能位於海外伺服器,導致下載速度緩慢。為了提高下載速度,我們可以使用pip鏡像來源。什麼是pip鏡像來源?簡單來說,就

MetaMask(中文也叫小狐狸錢包)是一款免費的、廣受好評的加密錢包軟體。目前,BTCC已支援綁定MetaMask錢包,綁定後可使用MetaMask錢包進行快速登錄,儲值、買幣等,且首次綁定還可獲得20USDT體驗金。在BTCCMetaMask錢包教學中,我們將詳細介紹如何註冊和使用MetaMask,以及如何在BTCC綁定並使用小狐狸錢包。 MetaMask錢包是什麼? MetaMask小狐狸錢包擁有超過3,000萬用戶,是當今最受歡迎的加密貨幣錢包之一。它可免費使用,可作為擴充功能安裝在網絡

在如今雲端儲存已成為我們日常生活和工作中不可或缺的一部分。百度網盤作為國內領先的雲端儲存服務之一,憑藉其強大的儲存功能、高效的傳輸速度以及便捷的操作體驗,贏得了廣大用戶的青睞。而且無論你是想要備份重要文件、分享資料,還是在線上觀看影片、聽取音樂,百度網盤都能滿足你的需求。但很多用戶可能對百度網盤app的具體使用方法還不了解,那麼這篇教學就將為大家詳細介紹百度網盤app如何使用,還有疑惑的用戶們就快來跟著本文詳細了解一下吧!百度雲網盤怎麼用:一、安裝首先,下載並安裝百度雲軟體時,請選擇自訂安裝選

網易郵箱,作為中國網友廣泛使用的一種電子郵箱,一直以來以其穩定、高效的服務贏得了用戶的信賴。而網易信箱大師,則是專為手機使用者打造的信箱軟體,它大大簡化了郵件的收發流程,讓我們的郵件處理變得更加便利。那麼網易信箱大師該如何使用,具體又有哪些功能呢,下文中本站小編將為大家帶來詳細的內容介紹,希望能幫助到大家!首先,您可以在手機應用程式商店搜尋並下載網易信箱大師應用程式。在應用寶或百度手機助手中搜尋“網易郵箱大師”,然後按照提示進行安裝即可。下載安裝完成後,我們打開網易郵箱帳號並進行登錄,登入介面如下圖所示
