作用域
1 --- 變量能夠被訪問的‘區(qū)域’,在這個(gè)區(qū)域外便不會(huì)被訪問到
2 --- 作用域分為全局作用域和局部作用域
全局作用域
在標(biāo)簽<script>中和,js文件的區(qū)域就是全局作用域,在此聲明的變量可以被其作用域下的函數(shù)內(nèi)部訪問到
代碼示范:

輸出結(jié)果:

提示:函數(shù)內(nèi)未聲明的變量為全局變量,但是不推薦使用。盡量先聲明變量再使用
局部作用域
局部作用域分為函數(shù)作用域和塊級(jí)作用域
函數(shù)作用域
在函數(shù)中聲明的變量外界無法訪問到,只能函數(shù)內(nèi)部訪問
代碼:
function?foo(){
??????let?a?=?4
??????console.log(a) // 結(jié)果:4
????}
????foo()
?comsole.log(a) // 報(bào)錯(cuò)未定義
總結(jié):
1.函數(shù)內(nèi)部聲明的變量,外界無法被訪問
2.函數(shù)的參數(shù)也是函數(shù)內(nèi)部的局部變量
3.不同函數(shù)之間無法調(diào)用對(duì)方的變量
4.函數(shù)執(zhí)行完畢,函數(shù)內(nèi)部變量就會(huì)被清空,再次調(diào)用函數(shù)時(shí)會(huì)被創(chuàng)建
塊級(jí)作用域
在 js(javaScript簡稱){} 花括號(hào)包圍的區(qū)域就是代碼塊,也是塊級(jí)作用域,內(nèi)部變量將有可能被訪問
{
?????let?arr?=?[1,2,3]
?????console.log(arr)?//?輸出[1,2,3]
???}
???console.log(arr)?//?arr?is?not?defined(未定義)
總結(jié):
1-- let聲明的變量會(huì)形成塊級(jí)作用域,var不會(huì),推薦使用let
2 -- const聲明的變量會(huì)形成塊級(jí)作用域
3 -- 不同塊級(jí)作用域之間的變量無法訪問
內(nèi)部變量將有可能被訪問:閉包
作用域鏈
函數(shù)內(nèi)部允許創(chuàng)建新的函數(shù),新的函數(shù)會(huì)產(chǎn)生新的作用域,這樣的嵌套作用域形成了鏈狀的結(jié)果所以叫作用域鏈
在函數(shù)被執(zhí)行時(shí),會(huì)優(yōu)先查找當(dāng)前函數(shù)作用域中查找變量,如果當(dāng)前作用域查找不到則會(huì)依次逐級(jí)查找父級(jí)作用域直到全局作用域
?function?foo(){
????let?a?=?2
????console.log(a)
????console.log(b)?//?報(bào)錯(cuò)
????function?g(){
??????let?b?=?5
??????console.log(a)?//?2
??????console.log(b)?//?5
????}
????g()
??}
????console.log(a)//?報(bào)錯(cuò)
????console.log(b)?//?報(bào)錯(cuò)
????foo()
閉包
閉包是一種特殊的函數(shù),閉包能夠訪問函數(shù)作用域中的變量
?function?foo(){
????let?a?=?2
????function?g(){
??????console.log(a+1)?// 輸出3
????}
???return?g()
??}
??foo()
總結(jié):
1.閉包是一種函數(shù),不過是從函數(shù)內(nèi)部返回
2.閉包可以創(chuàng)建外部訪問的隔離作用域,避免全局變量污染
3.但是閉包可能造成內(nèi)存泄漏
變量提升
變量提升是javascript中特殊的現(xiàn)象,允許變量在sheng聲明前被訪問,出現(xiàn)在同一作用域
變量在未聲明時(shí)即被訪問會(huì)報(bào)錯(cuò)
變量在聲明前被調(diào)用時(shí),變量值為undefined,工作中推薦先聲明再調(diào)用
let不存在變量提升所以推薦使用let聲明變量