作用域
在一些類似C語(yǔ)言的編程語(yǔ)言中,花括號(hào)內(nèi)的每一段代碼都具有各自的作用域,而且變量在聲明它們的代碼段之外是不可見(jiàn)的,我們稱為塊級(jí)作用域。
而在js中并沒(méi)有塊級(jí)作用域,取而代之的使用了函數(shù)作用域:變量在聲明它們的函數(shù)體以及函數(shù)體嵌套的任意函數(shù)體都是定義的
如下:
function test(o){
var i = 0; // i在整個(gè)函數(shù)體內(nèi)均是有定義的
if(typeOf o == "object"){
var j = 0; // j在函數(shù)體內(nèi)是有定義的,不僅僅在這個(gè)代碼段
for(var k = 0; k < 10; k ++){ // k在函數(shù)體內(nèi)是有定義的,不僅僅在這個(gè)循環(huán)內(nèi)
console.log(k) // => 1~9
};
consloe.log(k) // => k已經(jīng)定義,輸出10
};
console.log(j) // => j已定義,但沒(méi)有初始化
}
- js的函數(shù)作用域是指在函數(shù)內(nèi)聲明的所有變量在函數(shù)體內(nèi)始終是可見(jiàn)的有意思的是,這就意味著變量在申明之前就甚至已經(jīng)可用(這種特性被非正式的成為“聲明提前”,即javascript引擎的“預(yù)編譯”時(shí)進(jìn)行)
如:
var scope = "global";
function f(){
console.log(scope); // 輸出undefined,而不是“global”
var scope = "local"; // 變量在這里賦值,在函數(shù)體內(nèi)的任何位置都有定義
console.log(scope); // 輸出“l(fā)ocal”
}
以上,雖然在函數(shù)f()外,scope被定義,但執(zhí)行到函數(shù)內(nèi)第一行時(shí)就被重新定義,但未被賦值,所以輸出undefined,運(yùn)行到第二行時(shí)才被賦值。為了方便理解上述函數(shù)f()可以寫(xiě)成
function f(){
var scope;
console.log(scope);
var scope = "local";
console.log(scope);
}
作用域鏈(純理論,理解!理解!理解?。?/h3>
- javascript是基于詞法作用域的語(yǔ)言,即通過(guò)閱讀包含變量定義在內(nèi)的源碼就能知道變量的作用域
- 全局變量在程序中始終有定義,局部變量在聲明它的函數(shù)體內(nèi)以及所嵌套的函數(shù)內(nèi)有定義
概念
概念
每一段js代碼都有一個(gè)與之關(guān)聯(lián)的作用域鏈,這個(gè)作用域鏈?zhǔn)且粋€(gè)對(duì)象列表或者鏈表,這組對(duì)象定義了這段代碼“作用域中”的變量,當(dāng)js需要找一個(gè)變量x時(shí),會(huì)從鏈中的第一個(gè)對(duì)象開(kāi)始,沒(méi)有就找下一個(gè),如果在一個(gè)對(duì)象中找到名為x的屬性,就會(huì)停止,如果在鏈中沒(méi)有找到說(shuō)明該鏈中并不存在x,并最終拋出一個(gè)引用錯(cuò)誤(ReferenceError)異常.
- 在js最頂層的代碼中(也就是不包含在任何函數(shù)定義內(nèi)的代碼),作用域由一個(gè)全局對(duì)象組成。
- 在不包含嵌套的函數(shù)體內(nèi),作用域鏈上有兩個(gè)對(duì)象:
1.定義函數(shù)參數(shù)和局部變量的對(duì)象。
2.全局對(duì)象 - 在一個(gè)含有嵌套函數(shù)體內(nèi),作用域鏈上至少有三個(gè)對(duì)象
理解
- 當(dāng)定義一個(gè)函數(shù)時(shí),它實(shí)際上保存一個(gè)作用鏈。調(diào)用這個(gè)函數(shù)時(shí),將創(chuàng)建一個(gè)新的對(duì)象來(lái)儲(chǔ)存它的局部變量,并將這個(gè)對(duì)象添加至保存的那個(gè)作用鏈上,同時(shí)創(chuàng)建一個(gè)新的更長(zhǎng)的表示函數(shù)調(diào)用作用域的”鏈“
- 對(duì)于嵌套函數(shù)來(lái)講,每次調(diào)用一個(gè)外部函數(shù)時(shí),作用域都是不同的,內(nèi)部函數(shù)又會(huì)重新定義一遍。因?yàn)槊看握{(diào)用外部函數(shù)的時(shí)候,作用域鏈型都是不同的,內(nèi)部函數(shù)在每次調(diào)用的時(shí)候都有微妙的差別(在每次調(diào)用外部函數(shù)時(shí),內(nèi)部函數(shù)的代碼都是相同的,而且關(guān)聯(lián)這段代碼的作用域鏈也不同)。