web面試之JS預(yù)解析與變量提升區(qū)別
什么是預(yù)解析?
概念:
JS代碼在在代碼從上往下執(zhí)行前,瀏覽器會(huì)先把所有變量聲明解析一遍, 這個(gè)階段叫預(yù)解析。
詳講
尋找作用域中的var 和function聲明(匿名函數(shù)沒(méi)有function聲明,所以不會(huì)提升),然后對(duì)其進(jìn)行事先聲明, 并把賦值操作留在原地,再?gòu)纳系较聢?zhí)行代碼。這就是一個(gè)預(yù)解析的過(guò)程。
變量和函數(shù)預(yù)解析的區(qū)別
在預(yù)解析時(shí),會(huì)把所有用 var 聲明的變量, 和 function 聲明的函數(shù),提升到所在的作用域最頂端
var聲明的變量, 在預(yù)解析的時(shí), 只是提前了聲明, 賦值語(yǔ)句依然留在原地;
function 聲明的函數(shù), 在預(yù)解析的時(shí), 會(huì)提前聲明并同時(shí)定義, 函數(shù)執(zhí)行的時(shí)候,函數(shù)內(nèi)部才會(huì)進(jìn)行預(yù)解析。
注意: 匿名函數(shù)沒(méi)有function聲明,所以不會(huì)提升
重復(fù)聲明var變量
var重復(fù)聲明時(shí):若已經(jīng)存在,編譯器會(huì)忽略 var 繼續(xù)向下編譯;
若不存在,則順著作用域鏈向上查找,
若沒(méi)有找到,會(huì)在本作用域聲明該變量
變量提升和函數(shù)提升優(yōu)先級(jí)
總結(jié):
函數(shù)提升優(yōu)先級(jí)高于變量提升,且不會(huì)被同名變量聲明時(shí)覆蓋,但是會(huì)被變量賦值后覆蓋
下面內(nèi)容轉(zhuǎn)載自:
https://blog.csdn.net/caoyafeicyf/article/details/53172532
函數(shù)優(yōu)先級(jí)大于變量?jī)?yōu)先級(jí)的深入探究
瀏覽器的預(yù)解析過(guò)程
先由一道小題進(jìn)入本文
var foo;
function foo(){}
console.log(foo);
結(jié)果是函數(shù)體function foo(){}
接著下面一道題:
function foo(){}var foo;console.log(foo);
結(jié)果也是函數(shù)體
function foo(){}
所有就有很多人說(shuō),函數(shù)聲明的優(yōu)先級(jí)大于變量聲明的優(yōu)先級(jí)。
那么,為什么呢?這就要從瀏覽器的預(yù)解析說(shuō)起了。
預(yù)解析流程
搜尋預(yù)解析關(guān)鍵字
尋找var關(guān)鍵字
尋找function關(guān)鍵字
執(zhí)行預(yù)解析
先應(yīng)用var關(guān)鍵字聲明的標(biāo)識(shí)符,使這些標(biāo)識(shí)符有定義
標(biāo)識(shí)符有定以后,使用這項(xiàng)標(biāo)識(shí)符就不會(huì)報(bào)錯(cuò)了但因?yàn)闆](méi)有賦值,因此其值為undefined
至此標(biāo)識(shí)符中保存了函數(shù)的引用
幾個(gè)需要注意的細(xì)節(jié)
- var 關(guān)鍵字對(duì)同一個(gè)標(biāo)識(shí)符重復(fù)使用時(shí),除第一次有效外,其他均做忽略處理。
- 預(yù)解析時(shí)先處理變量聲明,再處理函數(shù)聲明不
- 要糾結(jié)誰(shuí)的優(yōu)先級(jí)高,這些只是表面現(xiàn)象
- 懂得了預(yù)解析流程,一切都是浮云
看了預(yù)解析原理以后,下面咱們回到本文開(kāi)頭的兩題,分析下預(yù)解析的過(guò)程,詳細(xì)的了解為什么函數(shù)的優(yōu)先級(jí)高于變量的優(yōu)先級(jí)。follow me
先看第一個(gè)
var foo;
function foo(){}
console.log(foo);
預(yù)解析過(guò)程為:
var foo;<----變量聲明的var
var foo;<----函數(shù)聲明抽出的var
foo=function (){}<----函數(shù)聲明抽出的賦值
console.log(foo);
再來(lái)看第二個(gè)
function foo(){}
var foo;
console.log(foo);
預(yù)解析過(guò)程為:
var foo;<----變量聲明的var
var foo;<----函數(shù)聲明抽出的var
foo=function (){}<----函數(shù)聲明抽出的賦值
console.log(foo)
比較這兩個(gè),你發(fā)現(xiàn)了什么?原來(lái)他們的預(yù)解析過(guò)程一樣啊,這也就是為什么函數(shù)優(yōu)先級(jí)高于變量的原因了。
如果你理解了上面的內(nèi)容,那么下面再出一個(gè)題:
var a=1;
function a(){}
console.log(a);
這個(gè)瀏覽器是如何解析的呢?下面來(lái)跟著我的思路一起走:
1. 解析器首先搜尋var 關(guān)鍵字,結(jié)果第一行就發(fā)現(xiàn)了,把它提取到開(kāi)頭。
2. 解析器搜尋function關(guān)鍵字,第二行發(fā)現(xiàn)了,首先分離var+函數(shù)名,此時(shí)發(fā)現(xiàn)和第一步的一樣,不做處理,然后開(kāi)始分離函數(shù)的賦值,也就是a=function (){},此時(shí)a為函數(shù)體。
3. 解析器接著處理變量的賦值,a=1,上一步的函數(shù)體被覆蓋掉,此時(shí)a=1。
4. 最后處理console.log(a),自然而然的結(jié)果為1。
下面是解析器處理的代碼過(guò)程:
var a;<----變量聲明的var
var a;<----函數(shù)聲明抽出的var
a=function (){}<----函數(shù)聲明抽出的賦值
a=1;
console.log(a);
以上就是web面試之JS預(yù)解析與變量提升區(qū)別的詳細(xì)內(nèi)容,更多關(guān)于JS預(yù)解析與變量提升的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
javascript 學(xué)習(xí)筆記(四) 倒計(jì)時(shí)程序代碼
javascript 學(xué)習(xí)筆記(四) 倒計(jì)時(shí)程序代碼,需要的朋友可以參考下。2011-04-04
javascript中FOREACH數(shù)組方法使用示例
本文給大家介紹的是Array.prototype.forEach()的使用方法示例,希望對(duì)大家學(xué)習(xí)javascript能夠有所幫助。2016-03-03
自動(dòng)化測(cè)試讀寫64位操作系統(tǒng)的注冊(cè)表
本文主要介紹自動(dòng)化測(cè)試讀寫64位操作系統(tǒng)的注冊(cè)表,這里提供詳細(xì)的教程來(lái)實(shí)現(xiàn)自動(dòng)化讀寫64位操作系統(tǒng)的注冊(cè)表,希望能幫助測(cè)試軟件的朋友,有興趣的小伙伴可以參考下2016-08-08
js nextSibling屬性和previousSibling屬性概述及使用注意
nextSibling屬性:該屬性表示當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn);如果其后沒(méi)有與其同級(jí)的節(jié)點(diǎn),則返回null;previousSibling屬性:該屬性與nextSibling屬性的作用正好相反,接下來(lái)將詳細(xì)介紹下,感興趣的你不妨了解下哦,或許對(duì)你有所幫助2013-02-02
js腳本學(xué)習(xí) 比較實(shí)用的基礎(chǔ)
js腳本學(xué)習(xí) 比較實(shí)用的基礎(chǔ)...2006-09-09

