首頁 web前端 js教程 js函數和感嘆號的關係

js函數和感嘆號的關係

Mar 12, 2018 am 10:04 AM
javascript 關係

JavaScript開發中,我們可能會遇到一些js函數,而這些js函數的前面是帶有驚嘆號的,大家有沒有想過,加感嘆號的js函數和不加感嘆號的有什麼不同呢!我們一起看看本篇文章的講述吧!

如果在function之前加上驚嘆號 (!) 會怎麼樣?

例如下面的程式碼:

!function(){alert('iifksp')}()        // true
登入後複製

在控制台運行後得到的值時true,為什麼是true這很容易理解,因為這個匿名函數沒有回傳值,預設回傳的就是undefined,求反的結果很自然的就是true。所以問題不在於結果值,而是在於,為什麼求反操作能夠讓一個匿名函數的自調變的合法性?

平常我們可能會對新增括號來呼叫匿名函數的方式更為習慣:

(function(){alert('iifksp')})()        // true
登入後複製

或:

(function(){alert('iifksp')}())        // true
登入後複製

雖然上述兩者括號的位置不同,不過效果完全一樣。

那麼,是什麼好處使得為數不少的人對這種嘆號的方式情有獨鍾?如果只是為了節省一個字元未免太沒有必要了,這樣算來即使一個100K的庫恐怕也節省不了多少空間。既然不是空間,就是說也許還有時間上的考量,事實很難說清,文章的最後有提到性能。

回到核心問題,為什麼能這麼做?甚至更核心的問題是,為什麼必須這麼做?

其實無論是括號,或是感嘆號,讓整個語句合法做的事情只有一件,就是讓一個函數宣告語句變成了一個表達式

function a(){alert('iifksp')}        // undefined
登入後複製

這是一個函數聲明,如果在這麼一個聲明後直接加上括號調用,解析器自然不會理解而報錯:

function a(){alert('iifksp')}()        // SyntaxError: unexpected_token
登入後複製

因為這樣的程式碼混淆了函數宣告和函數調用,以這種方式宣告的函數 a,就應該以 a(); 的方式調用。

但是括號則不同,它將一個函數宣告轉換成了一個表達式,解析器不再以函數宣告的方式處理函數a,而是作為一個函數表達式處理,也因此只有在程式執行到函數a時它才能被存取。

所以,任何消除函數宣告和函數表達式間歧義的方法,都可以被解析器正確辨識。 例如:

var i = function(){return 10}();        // undefined
1 && function(){return true}();        // true
1, function(){alert('iifksp')}();        // undefined
登入後複製

賦值,邏輯,甚至是逗號,各種運算子都可以告訴解析器,這個不是函數聲明,它是個函數表達式。而且,對函數一元運算可以算的上是消除歧義最快的方式,感嘆號只是其中之一,如果不在乎返回值,這些一元運算都是有效的:

!function(){alert('iifksp')}()        // true
+function(){alert('iifksp')}()        // NaN
-function(){alert('iifksp')}()        // NaN
~function(){alert('iifksp')}()        // -1
登入後複製

甚至下面這些關鍵字,都能很好的工作:

void function(){alert('iifksp')}()        // undefined
new function(){alert('iifksp')}()        // Object
delete function(){alert('iifksp')}()        // true
登入後複製

最後,括號做的事情也是一樣的,消除歧義才是它真正的工作,而不是把函數作為一個整體,所以無論括號括在宣告上還是把整個函數都括在裡面,都是合法的:

(function(){alert('iifksp')})()        // undefined
(function(){alert('iifksp')}())        // undefined
登入後複製

說了這麼多,其實在說的一些都是最為基礎的概念-語句,表達式,表達式語句,這些概念如同指標與指標變數一樣容易產生混淆。雖然這種混淆對程式設計無表徵影響,但卻是一塊絆腳石隨時可能因為它而頭部破血流。

最後討論下性能。我在jsperf上簡單建立了一個測試:http://jsperf.com/js-funcion-expression-speed ,可以用不同瀏覽器訪問,運行測試查看結果。我也同時將結果羅列如下表所示(由於我比較窮,測試配置有點丟人不過那也沒辦法:奔騰雙核心1.4G,2G內存,win7企業版):

js函數和感嘆號的關係

可見不同的方式產生的結果並不相同,而且,差異很大,因瀏覽器而異。

但我們還是可以從中找出很多共通點:new方法永遠最慢——這也是理所當然的。 其它方面很多差距其實不大,但有一點可以肯定的是,感嘆號並非最為理想的選擇。反觀傳統的括號在測試裡表現始終很快,在大多數情況下比感嘆號更快——所以平時我們常用的方式毫無問題,甚至可以說是最優的。 加減號在chrome時表現驚人,而且在其他瀏覽器下也普遍很快,比起感嘆號效果較好。

當然這只是個簡單測試,不能說明問題。但有些結論是有意義的:括號和加減號最優。

但是為什麼這麼多開發者鍾情於感嘆號?我覺得這只是一個習慣問題,它們之間的優劣完全可以忽略。一旦習慣了一種程式碼風格,那麼這種約定會讓程式從混亂變得可讀。如果習慣了感嘆號,我不得不承認,它比括號有更好的可讀性。我不用在閱讀時留意括號的匹配,也不用在寫作時粗心遺忘——

以上是js函數和感嘆號的關係的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles