一中符、函數(shù)的作用域
首先姜胖,作用域就是指變量的作用范圍
然后,在JS中只有兩個(gè)作用域:1.全局作用域淀散,2.局部作用域(函數(shù)作用域)
-
全局作用域
- 簡(jiǎn)介:
全局作用域就是函數(shù)作用域外的作用域右莱,處于window對(duì)象之中蚜锨; -
全局變量:
1.全局變量是指不在函數(shù)內(nèi)部創(chuàng)建的變量,全局變量都處于window對(duì)象之中慢蜓,如下變量就是在一個(gè)全局變量:
2.另外亚再,在函數(shù)內(nèi)部創(chuàng)建變量時(shí),如果不加var進(jìn)行聲明胀瞪,那么這個(gè)變量也是全局變量针余,
- 簡(jiǎn)介:
-
局部作用域(函數(shù)作用域)
- 簡(jiǎn)介:
局部作用域是指在創(chuàng)建了函數(shù)后,在函數(shù)內(nèi)部形成的作用域凄诞; -
局部變量:
1.局部變量是指在函數(shù)內(nèi)部通過(guò)var進(jìn)行聲明的變量,如下變量就是一個(gè)局部變量:
- 簡(jiǎn)介:
-
全局變量和局部變量的調(diào)用
-
在函數(shù)中忍级,如果函數(shù)需要傳入一個(gè)變量帆谍,而這個(gè)變量并不在它自身內(nèi)部,那么就可以調(diào)用全局下的變量:
-
全局作用域下不能調(diào)用函數(shù)內(nèi)的局部變量
-
那么如何在全局作用域下對(duì)局部變量進(jìn)行調(diào)用呢轴咱?有兩個(gè)辦法:1汛蝙、函數(shù)return這個(gè)變量再賦值;2朴肺、使用閉包窖剑;
1.函數(shù)return這個(gè)變量,再將return的值賦值給一個(gè)全局變量:
2.使用閉包戈稿,在函數(shù)內(nèi)部再創(chuàng)建一個(gè)函數(shù)西土,返回這個(gè)函數(shù):
-
- 關(guān)于關(guān)鍵詞var的兩點(diǎn)
-
在全局作用域下的函數(shù)中不加var對(duì)變量進(jìn)行聲明時(shí),就是全局變量:
-
在同一個(gè)作用域內(nèi)鞍盗,當(dāng)一個(gè)變量已經(jīng)被聲明并被賦值需了,后面再次對(duì)其進(jìn)行聲明,該變量的值不變:
-
二般甲、關(guān)于函數(shù)的作用域鏈
簡(jiǎn)介
1.函數(shù)的作用域鏈就是指函數(shù)在調(diào)用變量時(shí)所經(jīng)過(guò)的路徑肋乍,比如函數(shù)fn調(diào)用變量a,但是它自身并沒(méi)有變量a(沒(méi)有在函數(shù)內(nèi)部用var進(jìn)行聲明)敷存,于是就從全局作用域下找變量a墓造,找到就調(diào)用全局變量a,那么這個(gè)過(guò)程就是函數(shù)fn的作用域鏈锚烦;
2.要了解函數(shù)作用域鏈觅闽,首先就要知道在函數(shù)對(duì)象中,擁有一個(gè)內(nèi)部屬性[[Scope]]
挽牢,該內(nèi)部屬性包含了函數(shù)被創(chuàng)建的作用域中對(duì)象的集合谱煤,這個(gè)集合被稱為函數(shù)的作用域鏈,它決定了哪些數(shù)據(jù)能被函數(shù)訪問(wèn)禽拔。
3.簡(jiǎn)單來(lái)說(shuō):函數(shù)對(duì)變量的調(diào)用是由自身開(kāi)始向外一層一層找的刘离,距離自身最近變量被找到室叉,就調(diào)用該變量;-
畫出函數(shù)的作用域鏈
1.代碼如下:
2.首先因?yàn)樽兞刻嵘吐暶髑爸昧蛱瑁覀儗⒋a修改成下面這樣:
3.第一步找到全局作用域下茧痕,發(fā)現(xiàn)有全局變量i和全局變量fn,然后全局變量fn變成了一個(gè)函數(shù)恼除,于是可以寫出如下偽代碼:
4.找到函數(shù)fn作用域下踪旷,發(fā)現(xiàn)有局部變量i和函數(shù)fn2,但是因?yàn)闆](méi)有執(zhí)行豁辉,所以這兩項(xiàng)并未被創(chuàng)建令野,又因?yàn)楹瘮?shù)fn處于全局作用域下,所以它也可以對(duì)全局作用域下的變量進(jìn)行調(diào)用徽级,所以fn的[[Scope]]
包含全局作用域globalScope
:
5.然后在函數(shù)fn中有一個(gè)函數(shù)fn2气破,發(fā)現(xiàn)它里面沒(méi)有自身的局部變量,但是因?yàn)閒n2是在函數(shù)fn內(nèi)被聲明餐抢,所以fn2的[[Scope]]
包含fn的作用域fnScope
现使,并且fn2也可以對(duì)全局作用域下的變量進(jìn)行調(diào)用,所以也包含全局作用域globalScope(全局作用域)
;
6.執(zhí)行函數(shù)fn旷痕,進(jìn)入了fn的執(zhí)行上下文中fn execution context
碳锈,此時(shí)聲明了變量i以及函數(shù)fn2,i此時(shí)未被賦值欺抗,所以是i的值是undefined:
7.因?yàn)閕的值是undefined售碳,所以console.log(i)
得到的就是undefined,所以執(zhí)行fn得到的第一個(gè)結(jié)果就是undefined佩迟,然后將99賦值給了i团滥,i變?yōu)?9
8.然后執(zhí)行fn2,進(jìn)入到fn2的執(zhí)行上下文fn2 execution context
报强,fn2將100賦值給i灸姊,但是因?yàn)樗陨頉](méi)有變量i,于是先到上一層秉溉,也就是函數(shù)fn中找變量i力惯,得到fn中的i后進(jìn)行賦值,函數(shù)fn中的i變?yōu)榱?00召嘶,所以下面的console.log(i)
得到的值就是100父晶,函數(shù)fn執(zhí)行的第二個(gè)結(jié)果就是100;
9.執(zhí)行完函數(shù)fn后弄跌,進(jìn)入到全局作用域的執(zhí)行上下文global execution context
中甲喝,將10賦值給全局變量i,20賦值給全局變量fn铛只,然后因?yàn)橄旅娴?code>console.log(i)是在全局作用域下執(zhí)行埠胖,所以這里的i是全局變量的i糠溜,得到最后一個(gè)結(jié)果10;
10.所以這段代碼的執(zhí)行結(jié)果依次為undefined直撤、100非竿、10
,而以上這個(gè)一層一層向上找變量的過(guò)程就是作用域鏈谋竖;
三红柱、函數(shù)遞歸
- 什么是遞歸
遞歸簡(jiǎn)單說(shuō)來(lái)就是不斷地重復(fù)執(zhí)行同樣的代碼來(lái)解決問(wèn)題 - 函數(shù)的遞歸
1.特點(diǎn):
①:自己調(diào)用自己;
②:要設(shè)定終止條件蓖乘;
2.優(yōu)缺點(diǎn)
①:算法簡(jiǎn)單锤悄;
②:效率低; - 一個(gè)使用遞歸的簡(jiǎn)單例子嘉抒,求n的階乘
n!
比如求5的階乘就是5! = 5*4*3*2*1
由此可知逛球,n的階乘就是n! = n*(n-1)*(n-2)....
而(n-2) = (n - 1) - 1
由此可知代碼如下:
輸出結(jié)果: