前言
本文是轉(zhuǎn)載文膛堤,小編覺(jué)得不錯(cuò)于是分享給大家
JavaScript是一門(mén)解釋型的語(yǔ)言 , 想要運(yùn)行JavaScript代碼需要兩個(gè)階段
編譯階段: 編譯階段就是我們常說(shuō)的JavaScript預(yù)解釋?zhuān)A(yù)處理)階段,在這個(gè)階段JavaScript解釋器將完成把JavaScript腳本代碼轉(zhuǎn)換到字節(jié)碼
執(zhí)行階段: 在編譯階段JavaScript解釋器借助執(zhí)行環(huán)境把字節(jié)碼生成機(jī)械碼皂甘,并從上到下按順序執(zhí)行
本文就重點(diǎn)介紹預(yù)解釋?zhuān)蚣軋D如下:
一磅网、什么是預(yù)解釋
預(yù)解釋:JavaScript代碼執(zhí)行之前户盯,瀏覽器首先會(huì)默認(rèn)的把所有帶var和function的進(jìn)行提前的聲明或者定義
1.理解聲明和定義
聲明(declare):如var num;=>告訴瀏覽器在全局作用域中有一個(gè)num的變量了;如果一個(gè)變量只是聲明了但是沒(méi)有賦值喊崖,默認(rèn)的值是undefined
定義(defined):如num=12;=>給我們的變量進(jìn)行賦值。
2.對(duì)于帶var和function關(guān)鍵字的在預(yù)解釋的時(shí)候操作不一樣的
var =>在預(yù)解釋的時(shí)候只是提前的聲明
function =>在預(yù)解釋的時(shí)候提前的聲明+定義都完成了
3.預(yù)解釋只發(fā)生在當(dāng)前的作用域下雇逞。
例如:開(kāi)始只對(duì)window下的進(jìn)行預(yù)解釋?zhuān)挥泻瘮?shù)執(zhí)行的時(shí)候才會(huì)對(duì)函數(shù)中的進(jìn)行預(yù)解釋
二荤懂、作用域鏈
1.如何區(qū)分私有變量和全局變量?
1)在全局作用域下聲明(預(yù)解釋的時(shí)候)的變量是全局變量
2)只有函數(shù)執(zhí)行會(huì)產(chǎn)生私有的作用域,比如for(){}塘砸、if(){}和switch(){}都不會(huì)產(chǎn)生私有作用域
3)在"私有作用域中聲明的變量(var 聲明)"和"函數(shù)的形參"都是私有的變量节仿。在私有作用域中,代碼執(zhí)行的時(shí)保遇到了一個(gè)變量掉蔬,首先我們需要確定它是否為私有的變量廊宪,如果是私有的變量矾瘾,那么和外面的沒(méi)有在何的關(guān)系;如果不是私有的箭启,則往當(dāng)前作用域的上級(jí)作用域進(jìn)行查找壕翩,如果上級(jí)作用域也沒(méi)有則繼續(xù)查找,一直找到window為止傅寡,這就是作用域鏈放妈。
我們舉個(gè)例子來(lái)區(qū)別私有變量和全局變量:
判斷是否是私有變量一個(gè)標(biāo)準(zhǔn)就是是否是在函數(shù)中var聲明的變量和函數(shù)的形參都是私有的變量。本道題目在test函數(shù)中a是形參和var b定義的變量b都是私有變量荐操。
2.函數(shù)傳參
這是因?yàn)楫?dāng)函數(shù)執(zhí)行的時(shí)候,首先會(huì)形成一個(gè)新的私有的作用域芜抒,然后按照如下的步驟執(zhí)行:
1)如果有形參,先給形參賦值
2)進(jìn)行私有作用域中的預(yù)解釋
3)私有作用域中的代碼從上到下執(zhí)行
我們來(lái)看一道例題
3.JS中內(nèi)存的分類(lèi)
棧內(nèi)存:用來(lái)提供一個(gè)供JS代碼執(zhí)行的環(huán)境托启,即作用域(全局作用域/私有的作用域)
堆內(nèi)存:用來(lái)存儲(chǔ)引用數(shù)據(jù)類(lèi)型的值宅倒。對(duì)象存儲(chǔ)的是屬性名和屬性值,函數(shù)存儲(chǔ)的是代碼字符串屯耸。
三唉堪、全局作用域下帶var和不帶var的區(qū)別
我們先來(lái)看以下兩個(gè)例子:
當(dāng)你看到var num=12時(shí),可能會(huì)認(rèn)為只是個(gè)聲明肩民。但JavaScript實(shí)際上會(huì)將其看成兩條聲明語(yǔ)句:var num;和 num=12;第一個(gè)定義聲明是在預(yù)解釋階段進(jìn)行的唠亚。第二個(gè)賦值聲明會(huì)被留在原地等待執(zhí)行階段。num2=12 相當(dāng)于給window增加了一個(gè)叫做num2的屬性名持痰,屬性值是12灶搜;而var num=12 首先它相當(dāng)于給全局作用域增加了一個(gè)全局變量num,它也相當(dāng)于給window增加了一個(gè)屬性名num2工窍,屬性值是12割卖。兩者最大區(qū)別:帶var的可以進(jìn)行預(yù)解釋?zhuān)栽谫x值的前面執(zhí)行不會(huì)報(bào)錯(cuò);不帶var的是不能進(jìn)行預(yù)解釋的患雏,在前面執(zhí)行會(huì)報(bào)錯(cuò)鹏溯;
接下來(lái)我們舉例說(shuō)明:
例題1中帶var變量在私有作用域中可以預(yù)解釋?zhuān)缘谝粋€(gè)console打出來(lái)的值為undefined。私有作用域中出現(xiàn)的一個(gè)變量不是私有的淹仑,則往上級(jí)作用域進(jìn)行查找丙挽,上級(jí)沒(méi)有則繼續(xù)向上查找,一直找到window為止匀借,例題2中不帶var變量不是私有的颜阐,所以往上級(jí)找
四、預(yù)解釋五大毫無(wú)節(jié)操的表現(xiàn)
1.預(yù)解釋的時(shí)候不管你的條件是否成立吓肋,都要把帶var的進(jìn)行提前的聲明凳怨。
請(qǐng)看下面這道例題:
2.預(yù)解釋的時(shí)候只預(yù)解釋”=”左邊的,右邊的值,不參與預(yù)解釋
請(qǐng)看下面這道例題:
3.自執(zhí)行函數(shù):定義和執(zhí)行一起完成了肤舞。
自執(zhí)行函數(shù)定義的那個(gè)function在全局作用域下不進(jìn)行預(yù)解釋?zhuān)?dāng)代碼執(zhí)行到這個(gè)位置的時(shí)候定義和執(zhí)行一起完成了紫新。常見(jiàn)有以下幾種形式:
4.函數(shù)體中return下面的代碼雖然不再執(zhí)行了,但是需要進(jìn)行預(yù)解釋?zhuān)籸eturn后面跟著的都是我們返回的值李剖,所以不進(jìn)行預(yù)解釋?zhuān)?/p>
5.函數(shù)聲明和變量聲明都會(huì)被提升弊琴。但是一個(gè)值得注意的細(xì)節(jié)(這個(gè)細(xì)節(jié)可以出現(xiàn)在有多個(gè)“重復(fù)”聲明的代碼中)是函數(shù)會(huì)首先被提升,然后才是變量杖爽。在預(yù)解釋的時(shí)候敲董,如果名字已經(jīng)聲明過(guò)了,不需要從新的聲明慰安,但是需要重新的賦值腋寨;
我們先來(lái)看下兩個(gè)簡(jiǎn)單的例子:
當(dāng)遇到存在函數(shù)聲明和變量聲明都會(huì)被提升的情況,函數(shù)聲明優(yōu)先級(jí)比較高化焕,最后變量聲明會(huì)被函數(shù)聲明所覆蓋萄窜,但是可以重新賦值,所以上個(gè)例子可以等價(jià)為
接下來(lái)我們看下兩道比較復(fù)雜的題目:
1.一開(kāi)始預(yù)解釋?zhuān)瘮?shù)聲明和賦值一起來(lái),fn 就是function fn(){console.log(1);}撒桨;遇到var fn=10;不會(huì)重新再聲明查刻,但是遇到function fn(){console.log(2);}就會(huì)從重新賦值,所以一開(kāi)始fn()的值就是2
2.再執(zhí)行fn();值不變還是2
3.fn重新賦值為10凤类,所以運(yùn)行fn()時(shí)報(bào)錯(cuò)穗泵,接下去的語(yǔ)句就沒(méi)再執(zhí)行。
1.函數(shù)聲明優(yōu)先于變量聲明谜疤,預(yù)解釋時(shí)候佃延,函數(shù)聲明和賦值一起來(lái),a就是function a(){alert(10)} 夷磕,后面遇到var a=3履肃,也無(wú)需再重復(fù)聲明,所以先彈出function a(){alert(10)}
2.a()坐桩,執(zhí)行函數(shù)尺棋,然后彈出10
3.接著執(zhí)行了var a=3; 所以alert(a)就是顯示3
4.由于a不是一個(gè)函數(shù)了,所以往下在執(zhí)行到a()的時(shí)候绵跷, 報(bào)錯(cuò)膘螟。
原文:https://segmentfault.com/a/1190000017032008
最后:“相信有很多想學(xué)前端的小伙伴,今年年初我花了一個(gè)月整理了一份最適合2018年學(xué)習(xí)的web前端干貨抖坪,從最基礎(chǔ)的HTML+CSS+JS到移動(dòng)端HTML5等都有整理萍鲸,送給每一位前端小伙伴,53763擦俐,1707這里是小白聚集地,歡迎初學(xué)和進(jìn)階中的小伙伴握侧◎乔疲”
祝大家早日學(xué)有所成嘿期,拿到滿(mǎn)意offer,快速升職加薪埋合,走上人生巔峰备徐。