web面試之JS預(yù)解析與變量提升區(qū)別
什么是預(yù)解析?
概念:
JS代碼在在代碼從上往下執(zhí)行前,瀏覽器會先把所有變量聲明解析一遍, 這個階段叫預(yù)解析。
詳講
尋找作用域中的var 和function聲明(匿名函數(shù)沒有function聲明,所以不會提升),然后對其進行事先聲明, 并把賦值操作留在原地,再從上到下執(zhí)行代碼。這就是一個預(yù)解析的過程。
變量和函數(shù)預(yù)解析的區(qū)別
在預(yù)解析時,會把所有用 var
聲明的變量, 和 function
聲明的函數(shù),提升到所在的作用域最頂端
var
聲明的變量, 在預(yù)解析的時, 只是提前了聲明, 賦值語句依然留在原地;
function
聲明的函數(shù), 在預(yù)解析的時, 會提前聲明并同時定義, 函數(shù)執(zhí)行的時候,函數(shù)內(nèi)部才會進行預(yù)解析。
注意: 匿名函數(shù)沒有function聲明,所以不會提升
重復(fù)聲明var變量
var重復(fù)聲明時:若已經(jīng)存在,編譯器會忽略 var
繼續(xù)向下編譯;
若不存在,則順著作用域鏈向上查找,
若沒有找到,會在本作用域聲明該變量
變量提升和函數(shù)提升優(yōu)先級
總結(jié):
函數(shù)提升優(yōu)先級高于變量提升,且不會被同名變量聲明時覆蓋,但是會被變量賦值后覆蓋
下面內(nèi)容轉(zhuǎn)載自:
https://blog.csdn.net/caoyafeicyf/article/details/53172532
函數(shù)優(yōu)先級大于變量優(yōu)先級的深入探究
瀏覽器的預(yù)解析過程
先由一道小題進入本文
var foo; function foo(){} console.log(foo);
結(jié)果是函數(shù)體function foo(){}
接著下面一道題:
function foo(){}var foo;console.log(foo);
結(jié)果也是函數(shù)體
function foo(){}
所有就有很多人說,函數(shù)聲明的優(yōu)先級大于變量聲明的優(yōu)先級。
那么,為什么呢?這就要從瀏覽器的預(yù)解析說起了。
預(yù)解析流程
搜尋預(yù)解析關(guān)鍵字
尋找var關(guān)鍵字
尋找function關(guān)鍵字
執(zhí)行預(yù)解析
先應(yīng)用var關(guān)鍵字聲明的標識符,使這些標識符有定義
標識符有定以后,使用這項標識符就不會報錯了但因為沒有賦值,因此其值為undefined
至此標識符中保存了函數(shù)的引用
幾個需要注意的細節(jié)
- var 關(guān)鍵字對同一個標識符重復(fù)使用時,除第一次有效外,其他均做忽略處理。
- 預(yù)解析時先處理變量聲明,再處理函數(shù)聲明不
- 要糾結(jié)誰的優(yōu)先級高,這些只是表面現(xiàn)象
- 懂得了預(yù)解析流程,一切都是浮云
看了預(yù)解析原理以后,下面咱們回到本文開頭的兩題,分析下預(yù)解析的過程,詳細的了解為什么函數(shù)的優(yōu)先級高于變量的優(yōu)先級。follow me
先看第一個
var foo; function foo(){} console.log(foo);
預(yù)解析過程為:
var foo;<----變量聲明的var var foo;<----函數(shù)聲明抽出的var foo=function (){}<----函數(shù)聲明抽出的賦值 console.log(foo);
再來看第二個
function foo(){} var foo; console.log(foo);
預(yù)解析過程為:
var foo;<----變量聲明的var var foo;<----函數(shù)聲明抽出的var foo=function (){}<----函數(shù)聲明抽出的賦值 console.log(foo)
比較這兩個,你發(fā)現(xiàn)了什么?原來他們的預(yù)解析過程一樣啊,這也就是為什么函數(shù)優(yōu)先級高于變量的原因了。
如果你理解了上面的內(nèi)容,那么下面再出一個題:
var a=1; function a(){} console.log(a);
這個瀏覽器是如何解析的呢?下面來跟著我的思路一起走:
1. 解析器首先搜尋var 關(guān)鍵字,結(jié)果第一行就發(fā)現(xiàn)了,把它提取到開頭。
2. 解析器搜尋function關(guān)鍵字,第二行發(fā)現(xiàn)了,首先分離var+函數(shù)名,此時發(fā)現(xiàn)和第一步的一樣,不做處理,然后開始分離函數(shù)的賦值,也就是a=function (){}
,此時a為函數(shù)體。
3. 解析器接著處理變量的賦值,a=1
,上一步的函數(shù)體被覆蓋掉,此時a=1。
4. 最后處理console.log(a)
,自然而然的結(jié)果為1。
下面是解析器處理的代碼過程:
var a;<----變量聲明的var var a;<----函數(shù)聲明抽出的var a=function (){}<----函數(shù)聲明抽出的賦值 a=1; console.log(a);
以上就是web面試之JS預(yù)解析與變量提升區(qū)別的詳細內(nèi)容,更多關(guān)于JS預(yù)解析與變量提升的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript fontsize方法入門實例(按照指定的尺寸來顯示字符串)
這篇文章主要介紹了JavaScript fontsize方法入門實例,fontsize方法用于按照指定的尺寸來顯示字符串,需要的朋友可以參考下2014-10-10淺談JavaScript函數(shù)的四種存在形態(tài)
下面小編就為大家?guī)硪黄獪\談JavaScript函數(shù)的四種存在形態(tài)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06深入理解JavaScript系列(21):S.O.L.I.D五大原則之接口隔離原則ISP詳解
這篇文章主要介紹了深入理解JavaScript系列(21):S.O.L.I.D五大原則之接口隔離原則ISP詳解,本文講解了JavaScript接口、ISP與JavaScript、墮落的實現(xiàn)、靜態(tài)耦合、語義耦合、可擴展性等內(nèi)容,需要的朋友可以參考下2015-03-03javascript基礎(chǔ)語法——全面理解變量和標識符
下面小編就為大家?guī)硪黄猨avascript基礎(chǔ)語法——全面理解變量和標識符。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考,一起跟隨小編過來看看吧2016-06-06實現(xiàn)JavaScript的組成----BOM和DOM詳解
下面小編就為大家?guī)硪黄獙崿F(xiàn)JavaScript的組成----BOM和DOM詳解。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考,一起跟隨小編過來看看吧2016-05-05ajax提交表單實現(xiàn)網(wǎng)頁無刷新注冊示例
這篇文章主要介紹了ajax提交表單實現(xiàn)網(wǎng)頁無刷新注冊示例,需要的朋友可以參考下2014-05-05