詳解JavaScript中的函數(shù)聲明和函數(shù)表達(dá)式
JavaScript 中需要?jiǎng)?chuàng)建函數(shù)的話,有兩種方法:函數(shù)聲明、函數(shù)表達(dá)式,各自寫法如下:
// 方法一:函數(shù)聲明
function foo() {}
// 方法二:函數(shù)表達(dá)式
var foo = function () {};
另外還有一種自執(zhí)行函數(shù)表達(dá)式,主要用于創(chuàng)建一個(gè)新的作用域,在此作用域內(nèi)聲明的變量不會(huì)和其它作用域內(nèi)的變量沖突或混淆,大多是以匿名函數(shù)方式存在,且立即自動(dòng)執(zhí)行:
(function () {
// var x = ...
})();
此種自執(zhí)行函數(shù)表達(dá)式歸類于以上兩種方法的第二種,也算是函數(shù)表達(dá)式。
方法一和方法二都創(chuàng)建了一個(gè)函數(shù),且命名為 foo,但是二者還是有區(qū)別的。JavaScript 解釋器中存在一種變量聲明被提升(hoisting)的機(jī)制,也就是說(shuō)變量(函數(shù))的聲明會(huì)被提升到作用域的最前面,即使寫代碼的時(shí)候是寫在最后面,也還是會(huì)被提升至最前面。
例如以下代碼段:
alert(foo); // function foo() {}
alert(bar); // undefined
function foo() {}
var bar = function bar_fn() {};
alert(foo); // function foo() {}
alert(bar); // function bar_fn() {}
輸出結(jié)果分別是function foo() {}、undefined、function foo() {}和function bar_fn() {}。
可以看到 foo 的聲明是寫在 alert 之后,仍然可以被正確調(diào)用,因?yàn)?JavaScript 解釋器會(huì)將其提升到 alert 前面,而以函數(shù)表達(dá)式創(chuàng)建的函數(shù) bar 則不享受此待遇。
那么bar 究竟有沒(méi)有被提升呢,其實(shí)用 var 聲明的變量都會(huì)被提升,只不過(guò)是被先賦值為 undefined 罷了,所以第二個(gè) alert 彈出了 undefined。
所以,JavaScript 引擎執(zhí)行以上代碼的順序可能是這樣的:
- 創(chuàng)建變量 foo 和 bar,并將它們都賦值為 undefined。
- 創(chuàng)建函數(shù) foo 的函數(shù)體,并將其賦值給變量 foo。
- 執(zhí)行前面的兩個(gè) alert。
- 創(chuàng)建函數(shù) bar_fn,并將其賦值給 bar。
- 執(zhí)行后面的兩個(gè) alert。
注:
嚴(yán)格地說(shuō),再 JavaScript 中創(chuàng)建函數(shù)的話,還有另外一種方法,稱為“函數(shù)構(gòu)造法”:
var foo = Function('alert("hi!");');
var foo = new Function('alert("hi!");'); // 等同于上面一行
此方法以一個(gè)字符串作為參數(shù)形成函數(shù)體。但是用這種方法,執(zhí)行效率方面會(huì)打折扣,且似乎無(wú)法傳遞參數(shù),所以少用為妙。
相關(guān)文章
springboot整合shiro實(shí)現(xiàn)登錄驗(yàn)證授權(quán)的過(guò)程解析
這篇文章主要介紹了springboot整合shiro實(shí)現(xiàn)登錄驗(yàn)證授權(quán),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01
Spring Boot整合mybatis并自動(dòng)生成mapper和實(shí)體實(shí)例解析
本文是小編給大家總結(jié)的關(guān)于Spring Boot整合mybatis并自動(dòng)生成mapper和實(shí)體的內(nèi)容,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-05-05
java通過(guò)Jsoup爬取網(wǎng)頁(yè)過(guò)程詳解
這篇文章主要介紹了java通過(guò)Jsoup爬取網(wǎng)頁(yè)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
SpringMVC五大組件與執(zhí)行原理分析總結(jié)
這篇文章主要介紹了SpringMVC五大組件與執(zhí)行原理分析總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
SSM框架把日志信息保存到數(shù)據(jù)庫(kù)過(guò)程詳解
這篇文章主要介紹了SSM框架把日志信息保存到數(shù)據(jù)庫(kù)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

