JS中函數定義和函數表達式的區別


摘要: (function() {})();和(function(){}());的區別

Javascript中有2個語法都與function關鍵字有關,分別是:

函數定義:function FunctionName(FormalParameterList) { FunctionBody }

函數表達式:function [FunctionName](FormalParameterList) { FunctionBody }

從語法的定義上看,這兩者幾乎是一模一樣的(唯一的區別是函數表達式可以省略函數名稱),那么就解釋器而言,當遇到這個結構的語句時,判定為函數表達式還是函數定義呢?

就javascript的語法而言,如果一條語句是以function關鍵字開始,那么這段會被判定為函數定義。而函數定義是不能被立即執行的,這無疑會導致語法的錯誤(SyntaxError),因此就必須有一個辦法,使解析器可以將之識別為函數表達式。

前面已經說到,解析器識別函數定義的條件是以function關鍵字開始,那么自然,只要在function關鍵字的前面有任何其他的元素,就會從函數定義轉變為函數表達式,以下方法都是可以的,這個大家都知道:

~function() {}();

!function() {}();

void function() {}();

但是這幾個方法都有一個特點,就是看起來很別扭,所以現在為止,以括號包裹成了比較公認的方案

回到正題,括號包裹同樣有2個方式:(function() {})();和(function(){}());

他們的共通點是:都有括號。而括號在javascript中有2種作用:確立運算優先級,以及分組運算符,從代碼上看,顯然沒有進行數學或邏輯運算,因此我認為這里的括號屬於分組運算符。

根據標准,分組運算符的作用是:

Return the result of evaluating Expression. This may be of type Reference. 

返回評估括號中的表達式的結果。結果可能是Reference類型。

拋開像Reference類型這種詞匯,這里的一個關鍵詞應當是“ 評估 ”,但是關於分組運算符,又有一個很重要的下文:

This algorithm does not apply GetValue to the result of evaluating Expression.

這個算法不會對估算的結果使用GetValue。

有很多專用的名詞,看起來確實復雜,簡而言之,使用括號運算符本身不會讓括號中的代碼立即執行,只有當括號包含的這個“分組”參與其他運算時,才會執行。因此,(function(){})()這個語句,其實是首先用分組運算符評估了一個函數表達式,隨后參與“函數調用”。而(function(){}())這個語句,則是用分組運算符評估了一個函數調用,隨后由於語句的結束而被執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM