javascript
js变量提升_学习笔记:JS中的作用域和预解析
知識(shí)總結(jié):謝靜賢、湯昊
在javascript中作用域是非常重要的,本文將會(huì)說(shuō)明作用域以及我們?cè)诠ぷ?#xff0c;以及面試中的一些面試題,如果有不足的地方希望大家可以評(píng)論指出來(lái),自己一定會(huì)及時(shí)的改正錯(cuò)誤,避免大家走入一些誤區(qū)。
一:作用域
二.預(yù)解析??
三.作用域鏈
四.函數(shù)和變量提升
五.預(yù)解析中的一些變態(tài)機(jī)制?
一、作用域
一般情況下,一段代碼中所用到的名字并不總是有效可用的,而限定這個(gè)名字(變量)的可用性的代碼范圍就是這個(gè)名字的作用域,可用有效的減少變量名沖突
1、js的作用域(es6)之前:全局作用域,局部作用域
2、全局作用域:整個(gè)script標(biāo)簽?或者是單獨(dú)的JS文件
3、局部作用域(函數(shù)作用域),在函數(shù)內(nèi)部就是局部作用域,這個(gè)變量名只能在函數(shù)內(nèi)部使用
4、變量作用域
根據(jù)作用域的不同,變量分為全局變量,局部變量
?注意
如果在函數(shù)內(nèi)部沒(méi)有聲明直接賦值的變量也叫全局變量?
?函數(shù)的形參也是局部變量
?全局變量:只有瀏覽器關(guān)閉的時(shí)候才會(huì)銷(xiāo)毀,比較占內(nèi)存
?局部變量:當(dāng)程序執(zhí)行完畢就會(huì)銷(xiāo)毀,比較節(jié)約內(nèi)存
5、現(xiàn)階段JS沒(méi)有塊級(jí)作用域
在es6中有塊級(jí)作用域
塊級(jí)作用域?{}?if{}?for{}
6、作用域鏈
內(nèi)部函數(shù)訪(fǎng)問(wèn)外部函數(shù)?采用的就是鏈?zhǔn)竭@種結(jié)果就是作用域鏈?(就近原則)
二.預(yù)解析
1、什么是預(yù)解析:
預(yù)解析:在當(dāng)前作用域下,js代碼執(zhí)行之前,瀏覽器會(huì)把帶有var和function關(guān)鍵字的提前進(jìn)行聲明(var只聲明)或定義(function聲明并定義),并在內(nèi)存中安排好。然后再?gòu)纳系较聢?zhí)行js語(yǔ)句。
2、預(yù)解析的作用:
變量提升(Hoisting):在JS中,瀏覽器會(huì)把定義在后面的(變量或函數(shù))提升到前面當(dāng)前作用域的top處。也就是說(shuō)在當(dāng)前作用域中我們?cè)趈s代碼未執(zhí)行到聲明之前就可以使用了;
var和function預(yù)解析的不同
Var
var在預(yù)解釋的時(shí)候,只進(jìn)行提前的聲明,只要是通過(guò)var定義的,不管變量或者函數(shù),都是賦值undefined;
Function
function在預(yù)解釋的時(shí)候提前的聲明和定義都完成了,但是它儲(chǔ)存數(shù)據(jù)的空間里存儲(chǔ)的是字符串,沒(méi)有任何意義。
三.作用域鏈
JavaScript代碼中至少有一個(gè)作用域, 即全局作用域。
凡是代碼中有函數(shù),那么這個(gè)函數(shù)就構(gòu)成另一個(gè)作用域。
如果函數(shù)中還有函數(shù),那么在這個(gè)作用域中就又可以誕生一個(gè)作用域。
將這樣的所有的作用域列出來(lái),可以形成的結(jié)構(gòu)就稱(chēng)之為作用域鏈。
四. 函數(shù)和變量提升
1.? 函數(shù)提升(函數(shù)預(yù)解析):函數(shù)的聲明會(huì)被提升到當(dāng)前作用域的最上面,但是不會(huì)調(diào)用函數(shù)。
2.變量提升(變量預(yù)解析):變量的聲明會(huì)被提升到當(dāng)前作用域的最上面,變量的賦值不會(huì)提升。
變量提升和函數(shù)提升基本上是面試必問(wèn)題目
下面我們針對(duì)這個(gè)例子解析一下
我們知道變量和函數(shù)定義都會(huì)提升到作用域最前邊
唯一需要確認(rèn)的是變量和函數(shù)的先后順序
我們預(yù)想 函數(shù)是用會(huì)不會(huì)提升到最前邊呢?
按照我們預(yù)想的解析結(jié)果應(yīng)該是
// undefined // undefined // 報(bào)錯(cuò)
理由 函數(shù)在上var在下,第一個(gè)console時(shí)a未賦值,其結(jié)果是undefined,if為false 只剩最后一個(gè)console也是undefined 最后a is not a function.
不過(guò)結(jié)果是
我機(jī)智的認(rèn)為 預(yù)想錯(cuò)了?
這樣?對(duì)比一下結(jié)果人工解析結(jié)果 :1、a() 2、1 3、1 4、a() 報(bào)錯(cuò)
瀏覽器執(zhí)行結(jié)果:
看到這里一切完美,不過(guò)我還是重新搜索了一些高質(zhì)量文章,發(fā)現(xiàn)我錯(cuò)了,雖然執(zhí)行結(jié)果是對(duì)的,不過(guò)瀏覽器和人工解析還是不一樣的,和我們最開(kāi)始預(yù)想的一樣,函數(shù)優(yōu)先。
既然標(biāo)題說(shuō)到了變量 和 函數(shù),我們就一塊來(lái)說(shuō)說(shuō)
首先上邊已經(jīng)說(shuō)到我們預(yù)想和認(rèn)為的是錯(cuò)的。
正確解析順序是這樣的
但是,這個(gè)但是很重要瀏覽器執(zhí)行結(jié)果是:
why?這就要講講我所了解到的原理。
同名變量和函數(shù),函數(shù)會(huì)提升到最前邊,變量其次,那為什么結(jié)果不是我們?nèi)斯?zhí)行的undefined呢?原因是 變量會(huì)被忽略,是的是忽略。。。
完美!
還有呢?是的還有同名變量是怎樣的順序,同名函數(shù)是怎樣的順序。
同名變量
同名變量,聲明會(huì)被提升,后邊會(huì)忽略。
同名函數(shù)
我想你已經(jīng)猜到了,同名函數(shù)會(huì)被覆蓋。
五.預(yù)解析中的一些變態(tài)機(jī)制
不管條件是否成立,都要把帶var的進(jìn)行提前的聲明
JavaScript進(jìn)行預(yù)解析的時(shí)候,會(huì)忽略所有if條件,因?yàn)樵贓S6之前并沒(méi)有塊級(jí)作用域的概念。本例中會(huì)先將num預(yù)解析,而預(yù)解析會(huì)將該變量添加到window中,作為window的一個(gè)屬性。那么 'num' in window 就返回true,取反之后為false,這時(shí)代碼執(zhí)行不會(huì)進(jìn)入if塊里面,num也就沒(méi)有被賦值,最后console.log(num)輸出為undefined。
return下的代碼依然會(huì)進(jìn)行預(yù)解析
函數(shù)體中return下面的代碼,雖然不再執(zhí)行了,但是需要進(jìn)行預(yù)解析,return中的代碼,都是我們的返回值,所以不進(jìn)行預(yù)解析。
您的點(diǎn)贊是我繼續(xù)下去的動(dòng)力,謝謝!
總結(jié)
以上是生活随笔為你收集整理的js变量提升_学习笔记:JS中的作用域和预解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安卓-通讯录
- 下一篇: eureka 其它语言_SpringCl