作用域
變量的作用域
變量的作用域有兩種:全局變量和局部變量酣栈。
- 全局作用域: 最外層函數(shù)定義的變量擁有全局作用域,即對(duì)任何內(nèi)部函數(shù)來說汹押,都是可以訪問的:
<script>
var outerVar = "outer";
function fn(){
console.log(outerVar);
}
fn();//result:outer
</script>
- 局部作用域: 和全局作用域相反矿筝,局部作用域一般只在固定的代碼片段內(nèi)可訪問到,而對(duì)于函數(shù)外部是無法訪問的棚贾,最常見的例如函數(shù)內(nèi)部
<script>
function fn(){
var innerVar = "inner";
}
fn();
console.log(innerVar);// ReferenceError: innerVar is not defined
</script>
需要注意的是窖维,函數(shù)內(nèi)部聲明變量的時(shí)候,一定要使用var命令妙痹。如果不用的話铸史,你實(shí)際上聲明了一個(gè)全局變量!
<script>
function fn(){
innerVar = "inner";
}
fn();
console.log(innerVar);// result:inner
</script>
再來看一個(gè)代碼:
<script>
var scope = "global";
function fn(){
console.log(scope);//result:undefined
var scope = "local";
console.log(scope);//result:local;
}
fn();
</script>
很有趣吧怯伊,第一個(gè)輸出居然是undefined琳轿,原本以為它會(huì)訪問外部的全局變量(scope=”global”),但是并沒有耿芹。這可以算是javascript的一個(gè)特點(diǎn)崭篡,只要函數(shù)內(nèi)定義了一個(gè)局部變量,函數(shù)在解析的時(shí)候都會(huì)將這個(gè)變量“提前聲明”吧秕。
<script>
var scope = "global";
function fn(){
var scope;//提前聲明了局部變量
console.log(scope);//result:undefined
scope = "local";
console.log(scope);//result:local;
}
fn();
</script>
然而琉闪,也不能因此草率地將局部作用域定義為:用var聲明的變量作用范圍起止于花括號(hào)之間。 javascript并沒有塊級(jí)作用域 ,那什么是塊級(jí)作用域?javascript的作用域是相對(duì)函數(shù)而言的砸彬,可以稱為函數(shù)作用域颠毙。
作用域鏈
在JS中,函數(shù)的可以允許嵌套的砂碉。即吟秩,在一個(gè)函數(shù)的內(nèi)部聲明另一個(gè)函數(shù),類似這樣:
function A(){
var a=1;
function B(){ //在A函數(shù)內(nèi)部,聲明了函數(shù)B绽淘,這就是所謂的函數(shù)嵌套涵防。
var b=2;
}
}
對(duì)于A來說,A函數(shù)在執(zhí)行的時(shí)候沪铭,會(huì)創(chuàng)建其A函數(shù)的作用域壮池, 那么函數(shù)B在創(chuàng)建的時(shí)候,會(huì)引用A的作用域杀怠,類似下面這樣
函數(shù)B在執(zhí)行的時(shí)候椰憋,其作用域類似于下面這樣:
從上面的兩幅圖中可以看出,函數(shù)B在執(zhí)行的時(shí)候赔退,是會(huì)引用函數(shù)A的作用域的橙依。所以证舟,像這種函數(shù)作用域的嵌套就組成了所謂的函數(shù)作用域鏈。當(dāng)在自身作用域內(nèi)找不到該變量的時(shí)候窗骑,會(huì)沿著作用域鏈逐步向上查找女责,若在全局作用域內(nèi)部仍找不到該變量,則會(huì)拋出異常创译。