Javascript作用域鏈?zhǔn)荍avascript語(yǔ)言中非常重要的一個(gè)概念,它決定了變量和函數(shù)的可訪問范圍。在Javascript中,每一個(gè)函數(shù)都會(huì)形成一個(gè)自己的作用域,這個(gè)作用域會(huì)包含自身定義的變量和函數(shù)以及父級(jí)作用域中的變量和函數(shù)。在這篇文章中,我們將對(duì)Javascript作用域鏈進(jìn)行詳細(xì)的介紹。
作用域鏈的定義
在Javascript中,每一個(gè)函數(shù)在執(zhí)行時(shí)都會(huì)形成一個(gè)自己的作用域,這個(gè)作用域中包含了自身定義的變量和函數(shù)以及其所在的父級(jí)作用域中的變量和函數(shù)。當(dāng)我們引用一個(gè)變量或函數(shù)時(shí),Javascript會(huì)首先在當(dāng)前作用域中查找該變量或函數(shù),如果找不到則會(huì)在父級(jí)作用域中繼續(xù)查找,直到找到該變量或函數(shù)為止。
舉個(gè)例子,假如我們有一個(gè)嵌套的函數(shù)結(jié)構(gòu):
```
function A() {
let a = 10;
function B() {
let b = 5;
console.log(a + b);
}
B();
}
```
在這個(gè)例子中,函數(shù)`B`嵌套在函數(shù)`A`中,當(dāng)我們調(diào)用函數(shù)`B`時(shí),Javascript會(huì)首先在`B`的作用域中查找變量`b`,如果找到了就直接使用,如果沒有找到就會(huì)去`A`的作用域中查找,如果還是沒有找到,那么就會(huì)去全局作用域中查找。
作用域鏈的創(chuàng)建
在Javascript中,當(dāng)一個(gè)函數(shù)被創(chuàng)建時(shí),就會(huì)在內(nèi)存中創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象即為該函數(shù)的作用域,我們通常稱之為執(zhí)行上下文(Execution Context)。每一個(gè)執(zhí)行上下文中都會(huì)包含三個(gè)重要的屬性:變量對(duì)象、作用域鏈和this。在這里,我們主要講解作用域鏈的創(chuàng)建過(guò)程。
當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),Javascript會(huì)在函數(shù)的執(zhí)行上下文中創(chuàng)建一個(gè)變量對(duì)象(Variable Object)。這個(gè)變量對(duì)象中包含了當(dāng)前函數(shù)中定義的所有變量和函數(shù),同時(shí)也包含了外部環(huán)境的變量和函數(shù)。然后,Javascript會(huì)將它的作用域鏈(Scope Chain)添加到當(dāng)前的執(zhí)行上下文中。作用域鏈上的每一個(gè)對(duì)象都是一個(gè)執(zhí)行上下文的變量對(duì)象或全局對(duì)象。具體的創(chuàng)建過(guò)程可以參考下面的代碼:
```
var a = 10;
function foo() {
var b = 20;
function bar() {
var c = 30;
console.log(a + b + c);
}
bar();
}
foo();
```
當(dāng)執(zhí)行到函數(shù)`foo`時(shí),Javascript會(huì)創(chuàng)建一個(gè)函數(shù)執(zhí)行上下文,并在它的變量對(duì)象中添加`b`變量,然后將它的作用域鏈指向全局上下文中的變量對(duì)象。當(dāng)執(zhí)行到函數(shù)`bar`時(shí),Javascript會(huì)創(chuàng)建一個(gè)函數(shù)執(zhí)行上下文,并在它的變量對(duì)象中添加`c`變量,然后將它的作用域鏈指向函數(shù)`foo`上下文中的變量對(duì)象,同時(shí)也包含了全局上下文中的變量對(duì)象。因此,當(dāng)我們?cè)诤瘮?shù)`bar`中引用變量`a`時(shí),Javascript會(huì)在全局上下文中查找找到這個(gè)變量。
作用域鏈的修改
在Javascript中,作用域鏈可以被修改,這通常發(fā)生在函數(shù)中調(diào)用其他函數(shù)的時(shí)候。當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),Javascript會(huì)創(chuàng)建一個(gè)新的執(zhí)行上下文,并將它的變量對(duì)象添加到作用域鏈的前端,這樣就形成了一個(gè)新的作用域鏈。下面的代碼可以幫助我們更好地理解這個(gè)過(guò)程:
```
var a = 10;
function foo() {
var b = 20;
function bar() {
var c = 30;
console.log(a + b + c);
}
return bar;
}
var baz = foo();
baz(); // 輸出60
```
在這個(gè)例子中,函數(shù)`foo`返回了函數(shù)`bar`,此時(shí)并沒有調(diào)用函數(shù)`bar`。當(dāng)我們將函數(shù)`foo`的返回值賦給`baz`時(shí),Javascript會(huì)創(chuàng)建一個(gè)新的執(zhí)行上下文,并將它的變量對(duì)象添加到作用域鏈的前端。因此,當(dāng)我們調(diào)用函數(shù)`baz`時(shí),Javascript可以在該函數(shù)的作用域中找到變量`a`、`b`和`c`。
總結(jié)
在這篇文章中,我們?cè)敿?xì)介紹了Javascript作用域鏈的概念、創(chuàng)建和修改過(guò)程,并通過(guò)代碼和舉例的方式進(jìn)行說(shuō)明。作用域鏈?zhǔn)荍avascript語(yǔ)言中非常重要的一個(gè)概念,它決定了我們?cè)诰帉慗avascript程序時(shí)變量和函數(shù)的可訪問范圍。因此,了解Javascript作用域鏈的原理和運(yùn)作方式對(duì)我們更好地編寫高質(zhì)量的Javascript程序具有重要的意義。
網(wǎng)站導(dǎo)航
- zblogPHP模板zbpkf
- zblog免費(fèi)模板zblogfree
- zblog模板學(xué)習(xí)zblogxuexi
- zblogPHP仿站zbpfang