在上一篇文章中,我們主要學(xué)習(xí)在JavaScript中邓嘹,如何定義函數(shù)(也稱方法)辕漂,使用函數(shù),如何使用arguments去規(guī)避傳參的風(fēng)險(xiǎn)吴超。這一篇文章我們主要學(xué)習(xí)在JavaScript中變量的作用域與解構(gòu)賦值。
概念一:在JavaScript中鸯乃,用var申明的變量實(shí)際上是有作用域的鲸阻。
我們首先來復(fù)習(xí)下在Java中成員變量和局部變量是如何定義和使用的。
成員變量:
在類里面定義的變量叫做成員變量缨睡;
如果在變量有static關(guān)鍵字修飾鸟悴,就叫作靜態(tài)變量或類變量;
如果該變量沒有static關(guān)鍵字修飾奖年,就叫作非靜態(tài)變量或?qū)嵗兞浚?/p>
局部變量:
方法內(nèi)定義的變量细诸、形參、代碼塊中定義的變量都叫做局部變量陋守;
另外震贵,成員變量可以不顯式初始化,它們可以由系統(tǒng)設(shè)定默認(rèn)值水评;
但是局部變量沒有默認(rèn)值猩系,在使用前必須賦值才可以使用。
還有中燥,在內(nèi)存中的位置也不一樣寇甸。
成員變量在所在類被實(shí)例化后,存在堆內(nèi)存中疗涉;局部變量在所在方法調(diào)用時(shí)拿霉,存在棧內(nèi)存空間中。
復(fù)習(xí)完了Java咱扣,那么首先討論變量的作用域的第一個(gè)話題绽淘,在JavaScript中,變量的全局作用域是什么偏窝?
首先收恢,不在任何函數(shù)內(nèi)定義的變量武学,就具有全局作用域。如下圖
實(shí)際上伦意,JavaScript默認(rèn)有一個(gè)全局對象window火窒,全局作用域的變量實(shí)際上被綁定到window的一個(gè)屬性,既然是綁定在window中驮肉,我們就可以直接使用熏矿,如下圖
我們在學(xué)習(xí)函數(shù)的基礎(chǔ)的時(shí)候說道每一個(gè)function有兩種表達(dá)形式:一種是純粹的function,還有一種是function就可以代表一個(gè)var變量离钝,因此票编,每一個(gè)具體的函數(shù)如果用var變量來表示的話,這也是一個(gè)全局變量
綜上:使用window對象卵渴,也可以直接調(diào)用上面的test方法慧域,實(shí)踐檢測:
結(jié)論:根據(jù)上面的例子,我們可以判斷JavaScript實(shí)際上有一個(gè)全局作用域浪读。任何變量(函數(shù)也視為變量)昔榴,如果沒有在當(dāng)前函數(shù)作用域中找到,就會(huì)繼續(xù)往上查找碘橘,最后如果在全局作用域中也沒有找到互订,則報(bào)ReferenceError錯(cuò)誤(也就是類似我們java的空指針)。
老司機(jī)可能會(huì)說痘拆,上面說到了仰禽,全局變量會(huì)綁定到window上。如果不同的JavaScript文件如果使用了相同的全局變量纺蛆,或者定義了相同名字的頂層函數(shù)吐葵,這種情況該怎么處理?
解決辦法:減少命名沖突的一個(gè)有效方法是把 自己的所有變量和函數(shù)全部綁定到一個(gè)全局變量中犹撒。
我們可以把自己的代碼放入到自己唯一INFO中(根據(jù)自己的需求去定義即可)折联,這樣會(huì)大大減少全局變量沖突的可能,而且會(huì)顯著提高代碼的閱讀性和質(zhì)量识颊。
說完了JavaScript變量的全局作用域诚镰,那么局部作用域是什么?
由于JavaScript的變量作用域?qū)嶋H上是在函數(shù)內(nèi)部祥款,但是我們在for循環(huán)等語句中是無法定義具有局部作用域的變量的清笨。為了解決塊級(jí)作用域,ES6引入了新的關(guān)鍵字let刃跛,用let關(guān)鍵字替代var可以申明一個(gè)塊級(jí)作用域的變量抠艾。
常量:
在JavaScript中,聲明常量的方式有兩種桨昙,第一種是在全局變量中使用检号,變量名全部大寫腌歉,這一種是通過書寫規(guī)范去表示這是一個(gè)常量,不要修改它的值齐苛;但是在?ES6 標(biāo)準(zhǔn)中翘盖,引入了新的關(guān)鍵字 const 去定義常量,這里就不演示了凹蜂。(簡單理解就是Java中的final關(guān)鍵字)
關(guān)于var申明的變量實(shí)際上是有作用域的必須記住的一些概念:
A:如果一個(gè)變量在函數(shù)(方法)體內(nèi)部申明馍驯,則該變量的作用域?yàn)檎麄€(gè)函數(shù)體,在函數(shù)外不可引用該變量玛痊。
B:如果兩個(gè)不同的函數(shù)各自申明了同一個(gè)變量汰瘫,那么該變量只在各自的函數(shù)體內(nèi)起作用。(只能用在自己的方法內(nèi))
C:JavaScript的函數(shù)可以嵌套擂煞,此時(shí)混弥,內(nèi)部函數(shù)可以訪問外部函數(shù)定義的變量,反過來則不行
D:如果內(nèi)部函數(shù)和外部函數(shù)的變量名重名怎么辦对省?那么剑逃,內(nèi)部函數(shù)的變量將“屏蔽”外部函數(shù)的變量。
拓展:變量提升
JavaScript的方法定義有個(gè)特點(diǎn)官辽,它首先會(huì)先掃描整個(gè)函數(shù)體的語句,把所有申明的變量“提升”到函數(shù)頂部粟瞬,第三行的 var x = 'Hello, ' + y ; ?這一行并沒有報(bào)錯(cuò)同仆,原因是變量y在稍后申明了。但是console.log 顯示 Hello, undefined裙品,說明變量 y 的值為undefined俗批。這正是因?yàn)镴avaScript引擎自動(dòng)提升了變量y的聲明,但不會(huì)提升變量y的賦值市怎。因此我們在方法內(nèi)部定義變量時(shí)岁忘,請嚴(yán)格遵守“在方法內(nèi)部首先申明所有變量,然后在使用”這一開發(fā)原則区匠。
說完了JavaScript中變量的作用域干像,接下來我們在談?wù)劷鈽?gòu)賦值。
解構(gòu)賦值:
什么是解構(gòu)賦值驰弄?
解構(gòu)賦值?就是可以同時(shí)對一組變量進(jìn)行賦值麻汰。從ES6開始,JavaScript引入了這一新特性戚篙,它大大提高了開發(fā)效率五鲫。它為什么會(huì)提高開發(fā)效率,我們先從數(shù)組說起岔擂。
首先位喂,如何把一個(gè)數(shù)組的元素分別賦值給幾個(gè)變量浪耘?有人說,簡單塑崖,洋洋灑灑就是以下代碼
嗯七冲,上面的方式的確做到了,輕松無痛苦弃舒。但是使用了新特性解構(gòu)賦值的話癞埠,先看圖
使用了解構(gòu)賦值就只有兩行代碼 即可完成上面的事情(x, y, z分別被賦值為數(shù)組對應(yīng)元素)。
需要注意的有以下幾點(diǎn):
A:對數(shù)組元素進(jìn)行解構(gòu)賦值時(shí)聋呢,多個(gè)變量要用[ ... ]括起來
B:如果數(shù)組本身還有嵌套苗踪,也可以通過下面的形式進(jìn)行解構(gòu)賦值。(注意嵌套層次和位置要保持一致)
C:解構(gòu)賦值還可以忽略某些元素
注意削锰,這里的 ?z 成功打印出了數(shù)值通铲,但是 x y 都拋出了異常,所以我們還是需要嚴(yán)格遵循代碼規(guī)范去編寫代碼
D:如果需要從一個(gè)對象中取出若干屬性器贩,也可以使用解構(gòu)賦值颅夺,便于快速獲取對象的指定屬性:
從圖中我們清楚的可以看到,我們成功的將 person對象的 name蛹稍、age吧黄、passport全部成功的打印出來了。
E:對一個(gè)對象進(jìn)行解構(gòu)賦值時(shí)唆姐,同樣可以直接對嵌套的對象屬性進(jìn)行賦值拗慨,但需要保證對應(yīng)層次一致即可。?如下圖
F:使用解構(gòu)賦值對對象屬性進(jìn)行賦值時(shí)奉芦,如果對應(yīng)的屬性不存在赵抢,變量將被賦值為undefined。
G:解構(gòu)賦值還可以使用默認(rèn)值声功,這樣就避免了不存在的屬性返回undefined的問題烦却,如下圖
這里沒有在person對象中聲明single字段,但是我們可以直接在解構(gòu)賦值里面使用默認(rèn)值先巴。
H:有些時(shí)候其爵,如果變量已經(jīng)被聲明了,再次賦值的時(shí)候伸蚯,正確的寫法也會(huì)報(bào)語法錯(cuò)誤醋闭,如下圖
解決辦法1:不單獨(dú)聲明 var變量 x,y,兩行合并成一行
解決辦法2:使用括號(hào)朝卒,如下圖(推薦用法):
目前支持解構(gòu)賦值的瀏覽器包括Chrome证逻,F(xiàn)irefox,Edge等。
本篇文章學(xué)習(xí)的是關(guān)于變量的作用域與解構(gòu)賦值囚企,篇幅較長內(nèi)容也很多丈咐,需要自己耗時(shí)間多消化,變量的作用域與解構(gòu)賦值的基本內(nèi)容就結(jié)束了龙宏。
未完待續(xù)棵逊。。银酗。
如果這篇文章對您有開發(fā)or學(xué)習(xí)上的些許幫助辆影,希望各位看官留下寶貴的star,謝謝黍特。
Ps:著作權(quán)歸作者所有,轉(zhuǎn)載請注明作者, 商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)蛙讥,非商業(yè)轉(zhuǎn)載請注明出處(開頭或結(jié)尾請?zhí)砑愚D(zhuǎn)載出處,添加原文url地址),文章請勿濫用,也希望大家尊重筆者的勞動(dòng)成果灭衷。