全面了解函數(shù)聲明與函數(shù)表達(dá)式、變量提升
函數(shù)的聲明方式
在定義一個(gè)函數(shù)的時(shí)候通常有兩種聲明方式:
foo(){}; // 函數(shù)聲明 var foo = function(){}; // 函數(shù)表達(dá)式
不同之處
1、函數(shù)表達(dá)式后面加括號(hào)可以直接執(zhí)行
2、函數(shù)聲明會(huì)提前預(yù)解析
預(yù)解析
讓我們先看一個(gè)例子:
foo(); // 函數(shù)聲明 foo_later(); // foo_later is not a function function foo(){ console.log('函數(shù)聲明'); } var foo_later = function(){ console.log('函數(shù)表達(dá)式'); }
可以看到,函數(shù)聲明foo被預(yù)解析了,它可以在其自身代碼之前執(zhí)行;而函數(shù)表達(dá)式foo_later則不能。要解決這個(gè)問題,我們先要弄清楚JavaScript解析器的工作機(jī)制。
變量提升(hoist)
JavaScript解析器會(huì)在自身作用域內(nèi)將變量和函數(shù)聲明提前(hoist),也就是說,上面的例子其實(shí)被解析器理解解析成了以下形式:
function foo(){ console.log('函數(shù)聲明'); } // 函數(shù)聲明全部被提前 var foo_later; // 函數(shù)表達(dá)式(變量聲明)僅將變量提前,賦值操作沒有被提前 foo(); foo_later(); foo_later = function(){ console.log('函數(shù)表達(dá)式'); }
這樣也就可以解釋,為什么在函數(shù)表達(dá)式之前調(diào)用函數(shù),會(huì)返回錯(cuò)誤了,因?yàn)樗€沒有被賦值,只是一個(gè)未定義變量,當(dāng)然無法被執(zhí)行。
同樣的,我們也可以試著猜測下面這段代碼的輸出結(jié)果:
console.log(declaredLater); var declaredLater = "Now it's defined!"; console.log(declaredLater);
該段代碼可以被解析成一下形式:
var declaredLater; console.log(declaredLater); // undefined declaredLater = "Now it's defined!"; console.log(declaredLater); // Now it's defined!
變量聲明被提到最前(所以不會(huì)報(bào)出變量不存在的錯(cuò)誤),但賦值沒有被提前,所以第一次的輸出結(jié)果是undefined。
需要注意的是
由于函數(shù)聲明會(huì)被預(yù)解析,所以不要使用此種方法來聲明不同函數(shù)。嘗試猜想下面例子的輸出結(jié)果:
if(true){ function aaa(){ alert('1'); } } else{ function aaa(){ alert('2'); } } aaa();
與我們預(yù)想的不同,該段代碼彈出的是“2”.這是因?yàn)閮蓚€(gè)函數(shù)聲明在if語句被執(zhí)行之前就被預(yù)解析了,所以if語句根本沒有用,調(diào)用aaa()的時(shí)候直接執(zhí)行了下面的函數(shù)。
總結(jié)
通過上面的講解可以總結(jié)如下:
•變量的聲明被提前到作用域頂部,賦值保留在原地
•函數(shù)聲明整個(gè)“被提前”
•函數(shù)作為值賦給變量時(shí)只有變量“被提前”了,函數(shù)沒有“被提前”
通過練習(xí)上面的實(shí)例自己多感受一下。另外,作為最佳實(shí)踐:變量聲明一定要放在作用域/函數(shù)的最上方(JavaScript 只有函數(shù)作用域?。?。
以上這篇全面了解函數(shù)聲明與函數(shù)表達(dá)式、變量提升就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 淺析函數(shù)聲明和函數(shù)表達(dá)式——函數(shù)聲明的聲明提前
- 淺談javascript 函數(shù)表達(dá)式和函數(shù)聲明的區(qū)別
- JavaScript中函數(shù)表達(dá)式和函數(shù)聲明及函數(shù)聲明與函數(shù)表達(dá)式的不同
- 詳解JavaScript中的函數(shù)聲明和函數(shù)表達(dá)式
- js中函數(shù)聲明與函數(shù)表達(dá)式
- JavaScript中的函數(shù)聲明和函數(shù)表達(dá)式區(qū)別淺析
- 淺析javascript中函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別
相關(guān)文章
利用JS解決ie6不支持max-width,max-height問題的方法
本篇文章主要介紹了利用JS解決ie6不支持max-width,max-height問題的方法。需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01Node.js實(shí)戰(zhàn) 建立簡單的Web服務(wù)器
本章我們同樣通過實(shí)戰(zhàn)的演練,利用Node.js建立一個(gè)簡單的Web服務(wù)器2012-03-03echarts如何實(shí)現(xiàn)帶百分比的橫向柱狀圖
近期在使用echart開發(fā)過程中遇到一些問題,需要開發(fā)橫向柱狀圖,下面這篇文章主要給大家介紹了關(guān)于echarts如何實(shí)現(xiàn)帶百分比的橫向柱狀圖的相關(guān)資料,需要的朋友可以參考下2021-12-12JS數(shù)組降維的實(shí)現(xiàn)Array.prototype.concat.apply([], arr)
這篇文章主要介紹了JS數(shù)組降維的實(shí)現(xiàn)Array.prototype.concat.apply([], arr),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04在IE6下發(fā)生Internet Explorer cannot open the Internet site錯(cuò)誤
最近在IE6下面時(shí)常會(huì)發(fā)生“Internet Explorer cannot open the Internet site ”錯(cuò)誤。2010-06-06JS控制表格實(shí)現(xiàn)一條光線流動(dòng)分割行的方法
這篇文章主要介紹了JS控制表格實(shí)現(xiàn)一條光線流動(dòng)分割行的方法,實(shí)例分析了javascript操作table表格元素的技巧,需要的朋友可以參考下2015-03-03JS獲取瀏覽器地址欄的多個(gè)參數(shù)值的任意值實(shí)例代碼
本文通過實(shí)例代碼給大家介紹了JS獲取瀏覽器地址欄的多個(gè)參數(shù)值的任意值,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的的朋友參考下吧2018-07-07JavaScript 報(bào)表展示實(shí)現(xiàn)代碼
以下是從網(wǎng)上找到的一段JavaScript實(shí)現(xiàn)圖形報(bào)表的代碼,對于想客戶端顯示報(bào)表的朋友可以參考下。2009-12-12