JavaScript中函數(shù)表達(dá)式和函數(shù)聲明及函數(shù)聲明與函數(shù)表達(dá)式的不同
函數(shù)表達(dá)式和函數(shù)聲明
在ECMAScript中,創(chuàng)建函數(shù)的最常用的兩個(gè)方法是函數(shù)表達(dá)式和函數(shù)聲明,兩者期間的區(qū)別是有點(diǎn)暈,因?yàn)镋CMA規(guī)范只明確了一點(diǎn):函數(shù)聲明必須帶有標(biāo)示符(Identifier)(就是大家常說的函數(shù)名稱),而函數(shù)表達(dá)式則可以省略這個(gè)標(biāo)示符:
函數(shù)聲明:
function 函數(shù)名稱 (參數(shù):可選){ 函數(shù)體 }
函數(shù)表達(dá)式:
function 函數(shù)名稱(可選)(參數(shù):可選){ 函數(shù)體 }
所以,可以看出,如果不聲明函數(shù)名稱,它肯定是表達(dá)式,可如果聲明了函數(shù)名稱的話,如何判斷是函數(shù)聲明還是函數(shù)表達(dá)式呢?ECMAScript是通過上下文來區(qū)分的,如果function foo(){}是作為賦值表達(dá)式的一部分的話,那它就是一個(gè)函數(shù)表達(dá)式,如果function foo(){}被包含在一個(gè)函數(shù)體內(nèi),或者位于程序的最頂部的話,那它就是一個(gè)函數(shù)聲明。
function foo(){} // 聲明,因?yàn)樗浅绦虻囊徊糠? var bar = function foo(){}; // 表達(dá)式,因?yàn)樗琴x值表達(dá)式的一部分 new function bar(){}; // 表達(dá)式,因?yàn)樗莕ew表達(dá)式 (function(){ function bar(){} // 聲明,因?yàn)樗呛瘮?shù)體的一部分 })();
還有一種函數(shù)表達(dá)式不太常見,就是被括號(hào)括住的(function foo(){}),他是表達(dá)式的原因是因?yàn)槔ㄌ?hào) ()是一個(gè)分組操作符,它的內(nèi)部只能包含表達(dá)式,我們來看幾個(gè)例子:
function foo(){} // 函數(shù)聲明
(function foo(){}); // 函數(shù)表達(dá)式:包含在分組操作符內(nèi)
命名函數(shù)表達(dá)式
提到命名函數(shù)表達(dá)式,理所當(dāng)然,就是它得有名字,前面的例子var bar = function foo(){};就是一個(gè)有效的命名函數(shù)表達(dá)式,但有一點(diǎn)需要記住:這個(gè)名字只在新定義的函數(shù)作用域內(nèi)有效,因?yàn)橐?guī)范規(guī)定了標(biāo)示符不能在外圍的作用域內(nèi)有效:
var f = function foo(){ return typeof foo; // foo是在內(nèi)部作用域內(nèi)有效 }; // foo在外部用于是不可見的 console.log(typeof foo); // "undefined" console.log(f()); // "function" var f = function foo(){ return foo; // foo是在內(nèi)部作用域內(nèi)有效 }; // foo在外部用于是不可見的 console.log(typeof foo); // "undefined" console.log( f()==f); // "function" console.log(f.name);//foo
既然,這么要求,那命名函數(shù)表達(dá)式到底有啥用???為啥要取名?
正如我們開頭所說:給它一個(gè)名字就是可以讓調(diào)試過程更方便,因?yàn)樵谡{(diào)試的時(shí)候,如果在調(diào)用棧中的每個(gè)項(xiàng)都有自己的名字來描述,那么調(diào)試過程就太爽了,感受不一樣嘛。
ps:JS中函數(shù)聲明與函數(shù)表達(dá)式的不同
Js中的函數(shù)聲明是指下面的形式:
function functionName(){ }
這樣的方式來聲明一個(gè)函數(shù),而函數(shù)表達(dá)式則是類似表達(dá)式那樣來聲明一個(gè)函數(shù),如:
var functionName = function(){ }
可能很多朋友在看到這兩一種寫法時(shí)會(huì)產(chǎn)生疑惑,這兩種寫法差不多,在應(yīng)用中貌似也都是可行的,那他們有什么差別呢?
事實(shí)上,js的解析器對(duì)函數(shù)聲明與函數(shù)表達(dá)式并不是一視同仁地對(duì)待的。對(duì)于函數(shù)聲明,js解析器會(huì)優(yōu)先讀取,確保在所有代碼執(zhí)行之前聲明已經(jīng)被解析,而函數(shù)表達(dá)式,如同定義其它基本類型的變量一樣,只在執(zhí)行到某一句時(shí)也會(huì)對(duì)其進(jìn)行解析,所以在實(shí)際中,它們還是會(huì)有差異的,具體表現(xiàn)在,當(dāng)使用函數(shù)聲明的形式來定義函數(shù)時(shí),可將調(diào)用語句寫在函數(shù)聲明之前,而后者,這樣做的話會(huì)報(bào)錯(cuò)。
相關(guān)文章
JS簡(jiǎn)單判斷字符在另一個(gè)字符串中出現(xiàn)次數(shù)的2種常用方法
這篇文章主要介紹了JS簡(jiǎn)單判斷字符在另一個(gè)字符串中出現(xiàn)次數(shù)的2種常用方法,結(jié)合實(shí)例形式分析了js字符串分割計(jì)算與正則操作2種實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-04-04JavaScript上傳文件時(shí)不用刷新頁面方法總結(jié)(推薦)
這篇文章主要介紹了JavaScript上傳文件時(shí)不用刷新頁面方法,用js+css代碼詳細(xì)介紹了操作過程,需要的朋友可以參考下2017-08-08基于SpringMVC+Bootstrap+DataTables實(shí)現(xiàn)表格服務(wù)端分頁、模糊查詢
這篇文章主要介紹了基于SpringMVC+Bootstrap+DataTables實(shí)現(xiàn)表格服務(wù)端分頁、模糊查詢的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10使用js完成節(jié)點(diǎn)的增刪改復(fù)制等的操作
本文為大家詳細(xì)介紹下使用js完成節(jié)點(diǎn)的增刪改復(fù)制等的操作,具體的實(shí)現(xiàn)如下,感興趣的朋友可以參考下2014-01-01JS+html5 canvas實(shí)現(xiàn)的簡(jiǎn)單繪制折線圖效果示例
這篇文章主要介紹了JS+html5 canvas實(shí)現(xiàn)的簡(jiǎn)單繪制折線圖效果,結(jié)合實(shí)例形式分析了js結(jié)合HTML5 canvas技術(shù)實(shí)現(xiàn)圖形繪制的數(shù)值運(yùn)算與數(shù)組遍歷等操作技巧,需要的朋友可以參考下2017-03-03Js實(shí)現(xiàn)中國公民身份證號(hào)碼有效性驗(yàn)證實(shí)例代碼
這篇文章主要介紹了Js實(shí)現(xiàn)中國公民身份證號(hào)碼有效性驗(yàn)證實(shí)例代碼,可以識(shí)別身份證號(hào)碼的正確性,有興趣的可以了解一下2017-05-05layui之table checkbox初始化時(shí)選中對(duì)應(yīng)選項(xiàng)的方法
今天小編就為大家分享一篇layui之table checkbox初始化時(shí)選中對(duì)應(yīng)選項(xiàng)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09