用php和mysql做網(wǎng)站網(wǎng)絡(luò)推廣常見的方法
作用域是指在程序中定義變量的區(qū)域,決定了這些變量在哪里可以被訪問和使用。JavaScript 中的作用域有全局作用域、函數(shù)作用域和塊級作用域。
1. 什么是作用域?
作用域是代碼中定義變量的區(qū)域,它決定了變量的可見性和生命周期。作用域規(guī)定了在程序中哪些部分可以訪問某個變量,以及變量在哪些地方是可用的。
作用域最大的作用就是隔離變量。
2. 全局作用域和函數(shù)作用域
- 全局作用域:全局作用域是指在代碼中任何地方都可以訪問的作用域。在全局作用域中聲明的變量擁有全局作用域,可以被代碼中的任何地方訪問。
let globalVar = 10;function test() {console.log(globalVar); // 可以訪問全局作用域中的變量
}
- 最外層函數(shù)和在最外層函數(shù)外面定義的變量擁有全局作用域
- 所有未定義直接賦值的變量自動聲明為擁有全局作用域
- window 對象的所有屬性擁有全局作用域
全局作用域很大的弊端就是全局污染。所以這就是為什么 jQuery 等庫的源碼,都會放在 立即執(zhí)行函數(shù) 中。
- 函數(shù)作用域:函數(shù)作用域是指在函數(shù)內(nèi)部聲明的變量只能在該函數(shù)內(nèi)部訪問的作用域。函數(shù)外部無法訪問函數(shù)內(nèi)部聲明的變量。
function test() {let localVar = 20;console.log(localVar); // 可以訪問函數(shù)作用域中的變量
}console.log(localVar); // 報錯,無法訪問函數(shù)作用域中的變量
值得注意的是:塊語句(大括號" {) "中間的語句) ,如if和switch條件語句或for和while循環(huán)語句,不像函數(shù),它們不會創(chuàng)建一個新的作用域。在塊語句中定義的變量將保留在它們已經(jīng)存在的作用域中。
3. 塊級作用域
在 ES6 中引入了塊級作用域,使用 let
和 const
關(guān)鍵字聲明的變量具有塊級作用域。塊級作用域指的是在代碼塊(如 if
、for
、while
、{}
等)內(nèi)部聲明的變量只在該代碼塊內(nèi)部可見。
if (true) {let blockVar = 30;console.log(blockVar); // 可以訪問塊級作用域中的變量
}console.log(blockVar); // 報錯,無法訪問塊級作用域中的變量
作用域鏈
作用域鏈?zhǔn)且环N鏈?zhǔn)浇Y(jié)構(gòu),用于查找和解析變量標(biāo)識符。
1. 什么是自由變量?
自由變量是指在當(dāng)前函數(shù)作用域中未聲明但被引用(使用)的變量。
當(dāng) JavaScript 引擎在當(dāng)前作用域中找不到某個變量時,它會沿著作用域鏈向上查找,直到找到該變量為止。如果在全局作用域中也找不到該變量,那么該變量就是一個自由變量。
let globalVar = 'Global Variable';function outerFunction() {let outerVar = 'Outer Variable';function innerFunction() {console.log(outerVar); // Outer Variable 是一個自由變量console.log(globalVar); // globalVar 是一個自由變量}innerFunction();
}outerFunction();
在上面的例子中,innerFunction
內(nèi)部引用了 outerVar
和 globalVar
,但在該函數(shù)作用域中都沒有聲明這兩個變量,因此它們都是自由變量。
2. 什么是作用域鏈?
作用域鏈?zhǔn)?JavaScript 中一種動態(tài)的數(shù)據(jù)結(jié)構(gòu),用于解析標(biāo)識符引用。當(dāng) JavaScript 引擎遇到變量引用時,它會沿著作用域鏈向上查找,直到找到對應(yīng)的變量或者到達全局作用域為止。作用域鏈?zhǔn)怯僧?dāng)前執(zhí)行環(huán)境的變量對象和所有外部環(huán)境的變量對象組成的鏈?zhǔn)浇Y(jié)構(gòu)。
3. 關(guān)于自由變量的取值
當(dāng) JavaScript 引擎在當(dāng)前作用域中找不到某個變量時,它會沿著作用域鏈向上查找。如果在作用域鏈的某個環(huán)境中找到了對應(yīng)的變量,則使用該變量的值;如果在作用域鏈的頂端(全局作用域)仍然找不到對應(yīng)的變量,則會拋出 ReferenceError 錯誤。
向上級(或者說父級)找這種說法是不太準(zhǔn)確的。
let x = 10
function fn() {console.log(x)
}
function show(f) {let x = 20;(function () {f() // 10 而不是 20})()
}
show(fn)
取自由變量的值要在創(chuàng)建 fn 的函數(shù)那個作用域中去取,無論 fn 在哪里調(diào)用。
這就是所謂的“靜態(tài)作用域”。作用域中的值在函數(shù)創(chuàng)建的時候,就已經(jīng)被存儲了,是靜態(tài)的。
作用域與執(zhí)行上下文
JavaScript屬于解釋性語言,JavaScript 的執(zhí)行分為兩個階段:解釋和執(zhí)行。
解釋階段:
- 詞法分析
- 語法分析
- 作用域規(guī)則確定
執(zhí)行階段:
- 創(chuàng)建執(zhí)行上下文
- 執(zhí)行函數(shù)代碼
- 垃圾回收
執(zhí)行上下文在運行時確定,隨時可能改變,作用域在定義時就確定,并且不會改變。