網(wǎng)站建設(shè)哪家更專業(yè)/網(wǎng)站推廣計(jì)劃書范文500字
一、作用域
作用域,即變量(變量作用域又稱上下文)和函數(shù)生效(能被訪問)的區(qū)域或集合
換句話說,作用域決定了代碼區(qū)塊中變量和其他資源的可見性
舉個(gè)粟子
function myFunction(){let name='小愛同學(xué)'
}
undefined
myFunction()
undefined
name
Uncaught ReferenceError: inVariable is not defined
上述例子中,函數(shù)myFunction內(nèi)部創(chuàng)建一個(gè)name變量,當(dāng)我們在全局訪問這個(gè)變量的時(shí)候,系統(tǒng)會(huì)報(bào)錯(cuò)
這就說明我們在全局是無法獲取到(閉包除外)函數(shù)內(nèi)部的變量
我們一般將作用域分成:
- 全局作用域
- 函數(shù)作用域
- 塊級作用域
全局作用域
任何不在函數(shù)中或是大括號(hào)中聲明的變量,都是在全局作用域下,全局作用域下聲明的變量可以在程序的任意位置訪問
var globalName = 'hello world'
undefined
function getName(){console.log(globalName)
}
undefined
getName()
undefined
函數(shù)作用域
函數(shù)作用域也叫局部作用域,如果一個(gè)變量是在函數(shù)內(nèi)部聲明的它就在一個(gè)函數(shù)作用域下面。這些變量只能在函數(shù)內(nèi)部訪問,不能在函數(shù)以外去訪問
function greet() {var greeting = 'Hello World!';console.log(greeting);
}
// 打印 'Hello World!'
greet();
// 報(bào)錯(cuò):Uncaught ReferenceError: greeting is not defined
console.log(greeting);
可見上述代碼中在函數(shù)內(nèi)部聲明的變量或函數(shù),在函數(shù)外部是無法訪問的,這說明在函數(shù)內(nèi)部定義的變量或者方法只是函數(shù)作用域
塊級作用域
ES6引入了let和const關(guān)鍵字,和var關(guān)鍵字不同,在大括號(hào)中使用let和const聲明的變量存在于塊級作用域中。在大括號(hào)之外不能訪問這些變量
{// 塊級作用域中的變量let greeting = 'Hello World!';var lang = 'English';console.log(greeting); // Prints 'Hello World!'
}
// 變量 'English'
console.log(lang);
// 報(bào)錯(cuò):Uncaught ReferenceError: greeting is not defined
console.log(greeting);
二、詞法作用域
詞法作用域,又叫靜態(tài)作用域,變量被創(chuàng)建時(shí)就確定好了,而非執(zhí)行階段確定的。也就是說我們寫好代碼時(shí)它的作用域就確定了,JavaScript 遵循的就是詞法作用域
var a = 2;
function foo(){console.log(a)
}
function bar(){var a = 3;foo();
}
bar()
由于JavaScript遵循詞法作用域,相同層級的 foo 和 bar 就沒有辦法訪問到彼此塊作用域中的變量,所以輸出2
三、作用域鏈
當(dāng)在Javascript中使用一個(gè)變量的時(shí)候,首先Javascript引擎會(huì)嘗試在當(dāng)前作用域下去尋找該變量,如果沒找到,再到它的上層作用域?qū)ふ?#xff0c;以此類推直到找到該變量或是已經(jīng)到了全局作用域
如果在全局作用域里仍然找不到該變量,它就會(huì)在全局范圍內(nèi)隱式聲明該變量(非嚴(yán)格模式下)或是直接報(bào)錯(cuò)
這里拿《你不知道的Javascript(上)》中的一張圖解釋:
把作用域比喻成一個(gè)建筑,這份建筑代表程序中的嵌套作用域鏈,第一層代表當(dāng)前的執(zhí)行作用域,頂層代表全局作用域
變量的引用會(huì)順著當(dāng)前樓層進(jìn)行查找,如果找不到,則會(huì)往上一層找,一旦到達(dá)頂層,查找的過程都會(huì)停止
舉個(gè)粟子
var sex = '男';
function person() {var name = '張三';function student() {var age = 18;console.log(name); // 張三console.log(sex); // 男 }student();console.log(age); // Uncaught ReferenceError: age is not defined
}
person();
上述代碼主要主要做了以下工作:
- student函數(shù)內(nèi)部屬于最內(nèi)層作用域,找不到name,向上一層作用域person函數(shù)內(nèi)部找,找到了輸出“張三”
- student內(nèi)部輸出cat時(shí)找不到,向上一層作用域person函數(shù)找,還找不到繼續(xù)向上一層找,即全局作用域,找到了輸出“男”
- 在person函數(shù)內(nèi)部輸出age時(shí)找不到,向上一層作用域找,即全局作用域,還是找不到則報(bào)錯(cuò)