婷婷中文字幕在线播放-鲁鲁网站内射亚洲污色-日韩国产欧美在线免费观看-国产精品一区二区不卡视频

在線咨詢
QQ咨詢
服務(wù)熱線

020-85201717

13725302004

業(yè)務(wù)微信

微信開發(fā)

TOP

網(wǎng)站前端開發(fā)過程常見問題

發(fā)布時間:2021-01-28 瀏覽:

Java中的作用域是js中比較重要的一部分,也是大多數(shù)面試中必考的內(nèi)容,我們有必要更加深入的了解下js中作用域。


看一個栗子


仔細(xì)閱讀以下Java代碼,你覺得運行結(jié)果會是什么呢?是 1 還是2?



不是1,也不是2,答案卻是是undefined.


為什么會產(chǎn)生這個讓人意外的結(jié)果呢?我們得來看下js中的預(yù)解析。


Java預(yù)解析


Java在瀏覽器中運行的過程分為兩個階段預(yù)解析階段 執(zhí)行階段,在Java引擎對Java代碼進(jìn)行執(zhí)行之前,需要進(jìn)行預(yù)先處理,然后再對處理后的代碼進(jìn)行執(zhí)行。


我們平時書寫的Java代碼并不是Java執(zhí)行的代碼(V8引擎讀取一行執(zhí)行一行這種理解是錯誤的),它需要預(yù)解釋后,再由引擎進(jìn)行執(zhí)行.


具體的解釋過程涉及到瀏覽器內(nèi)核的技術(shù)不屬于前端領(lǐng)域,不過我們可以淺顯的理解一下V8在處理Java的一般過程:


以上例中的var a = 2;為例,我們一般人的理解為聲明了一個值為2的變量a,但是在Java引擎處理時卻分為了兩個步驟:


1. 讀取var a后,在當(dāng)前作用域中查找是否有相同聲明,如果沒有就在當(dāng)前作用域集合中創(chuàng)建一個名為a的變量,否則忽略此聲明繼續(xù)進(jìn)行解析.


2. 接下來,V8引擎會處理a = 2的賦值操作,首先會詢問當(dāng)前作用域中是否有名為a的變量,如果有進(jìn)行賦值,否則繼續(xù)向上級作用域詢問.


Java執(zhí)行環(huán)境


我們上面提到的所謂java預(yù)解釋正是創(chuàng)建函數(shù)的執(zhí)行環(huán)境(又稱“執(zhí)行上下文”),只有搞定了java的執(zhí)行環(huán)境我們才能搞清楚一段代碼在執(zhí)行過后為什么產(chǎn)生這樣的結(jié)果。


我們用一段偽代碼表示創(chuàng)立的執(zhí)行環(huán)境



作用域鏈(scopeChain)包括下面提到的變量對象(variableObject)和所有父級執(zhí)行上下文中的變量對象.


變量對象(variableObject)是與執(zhí)行上下文相關(guān)的數(shù)據(jù)作用域,一個與上下文相關(guān)的特殊對象,其中存儲了在上下文中定義的變量和函數(shù)聲明:


· 變量


· 函數(shù)聲明


· 函數(shù)的形參


在有了這些基板概念之后我們可以梳理一下js引擎創(chuàng)建執(zhí)行的過程:


· 創(chuàng)建階段


· 創(chuàng)建Scope chain


· 創(chuàng)建variableObject


· 設(shè)置this


· 執(zhí)行階段


· 變量的值、函數(shù)的引用


· 執(zhí)行代碼


而變量對象的創(chuàng)建細(xì)節(jié)如下:


· 根據(jù)函數(shù)的參數(shù),創(chuàng)建并初始化arguments object


· 掃描函數(shù)內(nèi)部代碼,查找函數(shù)聲明(Function declaration)


· 對于所有找到的函數(shù)聲明,將函數(shù)名和函數(shù)引用存入變量對象中


· 如果變量對象中已經(jīng)有同名的函數(shù),那么就進(jìn)行覆蓋


· 掃描函數(shù)內(nèi)部代碼,查找變量聲明(Variable declaration)


· 對于所有找到的變量聲明,將變量名存入變量對象中,并初始化為"undefined"


· 如果變量名稱跟已經(jīng)聲明的形式參數(shù)或函數(shù)相同,則變量聲明不會干擾已經(jīng)存在的這類屬性


變量提升


正是由于以上的處理,產(chǎn)生了大家熟知的Java中的變量提升,具體以上代碼的執(zhí)行過程如以下偽代碼所示:


e9b1f6e788084169a327fc6341d534fe

ed2b77539d574e7db442dc59ff85fb16

e992ab74b608433ba400c4d1a53afc14






我們可以明顯看到,a變量在預(yù)解釋階段已經(jīng)被賦值undefined,在執(zhí)行階段js是自上而下單線執(zhí)行,當(dāng)console.log(a)執(zhí)行之時,a=2還沒有被執(zhí)行,a變量的值便是預(yù)處理階段被賦予的undefined,


函數(shù)聲明與函數(shù)表達(dá)式


我們看到,在編譯器處理階段,除了被var聲明的變量會有變量提升這一特性之外,函數(shù)也會產(chǎn)生這一特性,但是函數(shù)聲明與函數(shù)表達(dá)式兩種范式創(chuàng)建的函數(shù)卻表現(xiàn)出不同的結(jié)果.


我們先看一個實例,運行以下代碼



f成功被打印出來,而g函數(shù)出現(xiàn)了類型錯誤,這是什么原因呢?



我們看到,在預(yù)解釋階段函數(shù)聲明的f是被指向了正確的函數(shù)得以執(zhí)行,而函數(shù)表達(dá)式g被賦予undefined,undefined無法被當(dāng)作函數(shù)執(zhí)行因此報錯g is not a function.


沖突處理


通常情況下我們不會將同一變量變量重復(fù)聲明,但是出現(xiàn)了類似情況后,編譯器會如何處理這些沖突呢?


1. 變量之間沖突


執(zhí)行以下函數(shù):



結(jié)果顯而易見,后聲明變量值覆蓋前者的值


  1. 函數(shù)之間沖突



結(jié)果同變量沖突,后者覆蓋前者.


2. 函數(shù)與變量之間沖突



結(jié)果如下,函數(shù)聲明將覆蓋變量聲明


[Function: f]


ES6中的let


在ES6中出現(xiàn)了兩個最新的聲明語法let與const,我們以let為例,進(jìn)行測試看看與var的區(qū)別.



這段代碼直接報錯顯示未定義,let與const擁有類似的特性,阻止了變量提升,當(dāng)代碼執(zhí)行到console.log(a)時,執(zhí)行換將中a還從未被定義,因此產(chǎn)生了錯誤.返回。

日韩高清精品一区有码在线| 小嫩骚逼操死你视频| 亚洲 欧美 日韩 主播| 国产高清在线观看一区二区三区| 狗狗大鸡巴狂操美女| 精品久久久久中文字幕人| 最新免费高清无码片| 色老头av亚洲三区三区| 熟妇好大好深好爽| 黑人插中国女人逼| 爆操大奶骚货视频| 一区二区三区四区五六区| 白色紧身裤无码系列在线| 国产成人精品免费视频全| 骚货 淫水 国产| 男女边吃奶边做边爱视频| 女人的骚逼免费视频| 欧美大鸡巴操大骚逼| 黑人大鸡把操逼视频| 日韩 欧美 成人 免费| 又大黄又硬又爽免费视频| 啊服慢一点插入逼逼| 久久久中文字幕一区| 中文字幕欧美中日韩精品| 成人刺激性视频在线观看| av黄色资源在线观看| 美女肏肏逼应用下载| 久久国产精品二卡| 一区二区在线不卡| av黄色资源在线观看| 亚洲午夜av一区二区三区| 大鸡巴插美女小逼逼| 91偷自产一区二区三区蜜臀| 亚洲国产AV精品一区二区色欲 | 操美女逼逼色逼网| 黄片观看骚货浪荡| 亚洲精品自拍偷拍第一页| 西瓜在线看免费观看视频| 中文字幕亚洲精品女同一页| 免费国产香蕉视频在线观看| 大几吧插进小穴视频|