<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
首先,我們先研究一下JavaScript的變數作用域,研究作用域,我們不按照常規的文章那樣解釋概念,而是先給一個小demo,吊一下大家的胃口:
var a = 1; var b = 2; function pomp(){ alert(a); alert(b); b = 2; alert(b); var a = 3; alert(a); } pomp();
如果你的答案是對的,那麼你對JavaScript的作用域的理解已經是中等偏上了,可能有一些複雜的作用域你沒有掌握,但是簡單的開發已經沒有問題了;如果你不知道答案,那麼下面我就以這個例子為引,介紹一下JavaScript的變數作用域問題。
首先,如果有程式設計基礎的同學,一定知道對於任何的程式語言,都有區域性變數和全域性變數的概念:全域性變數的作用範圍是全域性的;而區域性變數往往在一個部分被定義和使用,在這個部分之外,它的空間就會被回收,我們就無法再使用它。常見的區域性變數出現的地方有:for迴圈、函數體、程式碼塊。
在這些“區域性”裡,區域性變數的優先順序是大於全域性變數的,這是什麼意思呢?我們再用一個小demo來解釋一下:
var a = 1 function pomp() { var a = 2 alert(a) } pomp() alert(a)
也就是說,我們在區域性和全域性都有一個變數a,那麼在區域性,指令碼直譯器會優先從最近的位置開始尋找,最近的位置,當然會有區域性>大於全域性的效果,於是第一個彈窗彈出的是2,第二個才是1。
介紹完了區域性變數和全域性變數,我們再回到最開始的那個demo的問題:
var a = 1; var b = 2; function pomp(){ alert(a); alert(b); b = 2; alert(b); var a = 3; alert(a); } pomp();
顯然,這裡的問題是,我們明明已經給a宣告為全域性變數,並同時給a賦值了,那為什麼會列印a為undefined呢?這就是JavaScript的另一個特點,就是直譯器在一行一行解釋程式碼之前,會給變數劃好它們的作用域:
最開始,a和b都被宣告並定義為全域性變數,a有值1,b有值2;此時,我們定義了一個函數pomp(),在函數內部,我們又建立了一個區域性變數a,這時候,按照剛才的分析,此時離得最近的其實應該是區域性變數a,這就解釋了為什麼第一次alert(a)不是彈出1,但是還是沒有解釋undefined。
undefined的原因是這樣的:在直譯器解釋程式碼之前,按照其他程式語言的叫法,我們稱這個時期是預編譯時期,在預編譯時期,由於函數體內也宣告和定義了變數a,於是自然地函數體內的a被劃歸到了區域性變數a,即我們可以認為已經執行了一句:var a,但是由於這是預編譯時期,並沒有執行var a = 3,因此此時我們可以理解為,只是執行了 var a,而a = 3是在後面才會執行,因此這是undefined的原因。
最後針對第一開始的demo做一個圖片,幫助大家理解JavaScript變數作用域:
並附帶一句總結:
當使用var關鍵字時,在區域性或者全域性中的任何位置,當某個變數被宣告後,無論是之前的哪個地方,都可以使用這個變數,只是會顯示undefined。
最初的JavaScript,只有var這個關鍵字,因此上面的作用域講解,說白了是針對的var關鍵字,那麼對於var關鍵字,這裡就不再多做贅述,而是給一個小demo理解一下:
alert(a) var a = 3 alert(a)
不過避免一些朋友從這裡才開始看起,我還是再複述一下:
var關鍵字宣告的變數,只要在區域性/全域性的任何一個地方被宣告,那麼在其他的地方,即使沒有被宣告,由於在預編譯階段該變數已經被宣告,於是它也是存在的,只是會顯示undefined,也就是未定義,而後當執行到var a = 3,它被定義了一個值3。
順便簡單嘮一下變數的宣告與定義的區別:
講完了var,其實作用域的難點也基本上結束了,但是由於是一篇完整的文章,下面對兩種新的JavaScript變數宣告關鍵字進行介紹:let和const,它們的作用域與var略有不同。
首先,我們還是先來一個demo:
alert(a) let a = 3 alert(a)
哎嘿,大家點選之後,是不是啥也沒有啊,這可不是我在惡作劇,而是確實是什麼也沒有,原因是,它報錯了(hahaha):
好傢伙,同樣的寫法,為啥var不報錯,let就報錯了呢?(注意,這裡用const是一樣的,const和let的作用域是相同的,也即用const一樣會報錯!)
原因是,大家苦var久矣,這個let關鍵字,就是更符合我們的思維邏輯的一種變數的宣告方式,在let的作用域中:
一個變數只會在它被宣告之後才可以使用,而不是像var一樣,在任何地方只要有宣告,那麼在前面的地方也可以用!
最後,我們簡單介紹一下const,const在let的基礎上,多了一個唯一性的概念:
const變數一經定義,就不能再修改它的值了,適合定義一些特定的常數,例如:
const pi = 3.14
const e = 2.7
const的作用域與let相同!
一口氣看完了三個關鍵字,我們最後再簡單梳理一下吧,在梳理之前,先上一個demo:
function demo() { for (var i = 1; i < 10; i++) { // } alert(i) for (let j = 1; j < 9; j++) { // } alert(j) } demo()
大家看到這裡似乎又有點小疑惑,因為我們知道for迴圈是一個區域性,那麼區域性的變數i和j,在for迴圈的外面,理應不存在才對,但是很顯然,我們如果核對了會發現,彈窗彈出了一個10,也就是說i此時值仍然保留為10,而j確實和我們想的一樣,是不存在的,它也確實報錯了:
那為啥會出現這種情況呢?原因是var關鍵字宣告的區域性變數,會在整個大的區域性退出時,才會回收記憶體,也就是說for迴圈雖然也是一個區域性,但是這個區域性是屬於function這個大區域性,因此才會出現仍然存在i,但是let顯然又一次達到了我們的預期!
關鍵字 | 作用域 | 值的特點 |
var | 變數在區域性/全域性任何地方被宣告,在對應的區域性/全域性的其他任何地方都可以直接使用(甚至在宣告之前使用),但是使用時若未定義,則出現undefined。 | 可以反覆修改 |
let | 變數只能在被宣告語句的後面才可以使用。 | 可以反覆修改 |
const | 變數只能在被宣告語句的後面才可以使用。 | 不可修改 |
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45