JS作用域以及變量提升

作用域

作用域(Scope)的概念和分類

概念:

通俗來(lái)講,作用域是一個(gè)變量或函數(shù)的作用范圍。作用域在函數(shù)定義時(shí),就已經(jīng)確定了。

目的:

為了提高程序的可靠性,同時(shí)減少命名沖突。

在 JS 中,一共有兩種作用域:

  1. 全局作用域:作用于整個(gè) script 標(biāo)簽內(nèi)部,或者作用于一個(gè)獨(dú)立的 JS 文件。
  2. 函數(shù)作用域(局部作用域):作用于函數(shù)內(nèi)的代碼環(huán)境。

全局作用域 和 window 對(duì)象
直接編寫在 script 標(biāo)簽中的 JS 代碼,都在全局作用域。全局作用域在頁(yè)面打開時(shí)創(chuàng)建,在頁(yè)面關(guān)閉時(shí)銷毀。
在全局作用域中有一個(gè)全局對(duì)象 window,它代表的是一個(gè)瀏覽器的窗口,由瀏覽器創(chuàng)建,我們可以直接使用。
創(chuàng)建的變量都會(huì)作為 window 對(duì)象的屬性保存。比如在全局作用域內(nèi)寫 var a = 100,這里的 a 等價(jià)于 window.a。
創(chuàng)建的函數(shù)都會(huì)作為window對(duì)象的方法保存。
在內(nèi)部作用域中可以訪問到外部作用域的變量,在外部作用域中無(wú)法訪問到內(nèi)部作用域的變量。

變量的作用域:
根據(jù)作用域的不同,變量可以分為兩類:全局變量、局部變量。

全局變量:
在全局作用域下聲明的變量,叫「全局變量」。在全局作用域的任何一地方,都可以訪問這個(gè)變量。
在全局作用域下,使用 var 聲明的變量是全局變量。
特殊情況:在函數(shù)內(nèi)不使用 var 聲明的變量也是全局變量(不建議這么用)。

局部變量:
定義在函數(shù)作用域的變量,叫「局部變量」。僅限函數(shù)內(nèi)部訪問這個(gè)變量。
在函數(shù)內(nèi)部,使用 var 聲明的變量是局部變量。
函數(shù)的形參也是屬于局部變量。

從執(zhí)行效率來(lái)看全局變量和局部變量:
全局變量:只有瀏覽器關(guān)閉時(shí)才會(huì)被銷毀,比較占內(nèi)存。
局部變量:當(dāng)其所在的代碼塊運(yùn)行結(jié)束后,就會(huì)被銷毀,比較節(jié)約內(nèi)存空間。

注意:
當(dāng)在函數(shù)作用域操作一個(gè)變量時(shí),它會(huì)先在自身作用域中尋找,如果有就直接使用(就近原則)。如果沒有則向上一級(jí)作用域中尋找,直到找到全局作用域;如果全局作用域中依然沒有找到,則會(huì)報(bào)錯(cuò) ReferenceError。

在函數(shù)中要訪問全局變量可以使用 window 對(duì)象。(比如說,全局作用域和函數(shù)作用域都定義了變量 a,如果想訪問全局變量,可以使用Window.a)

作用域的預(yù)處理

預(yù)處理(預(yù)解析)
瀏覽器在解析 JS 代碼之前,會(huì)進(jìn)行一個(gè)操作叫 預(yù)處理(預(yù)解析):將當(dāng)前 JS 代碼中所有變量的定義和函數(shù)的定義,放到所有代碼的最前面。
這種預(yù)解析,也稱之為聲明提前。

變量提升
使用 var 關(guān)鍵字聲明的變量( 比如 var a = 1),會(huì)在所有的代碼執(zhí)行之前被聲明(但是不會(huì)賦值),但是如果聲明變量時(shí)不是用 var 關(guān)鍵字(比如直接寫a = 1),則變量不會(huì)被聲明提前。

函數(shù)的聲明提前

函數(shù)聲明:
使用函數(shù)聲明的形式創(chuàng)建的函數(shù)function foo(){},會(huì)被聲明提前。
也就是說,整個(gè)函數(shù)會(huì)在所有的代碼執(zhí)行之前就被創(chuàng)建完成。所以,在代碼順序上,我們可以先調(diào)用函數(shù),再定義函數(shù)。

函數(shù)作用域的預(yù)處理

在函數(shù)作用域中,也有聲明提前的特性:
函數(shù)中,使用 var 關(guān)鍵字聲明的變量,會(huì)在函數(shù)中所有的代碼執(zhí)行之前被聲明。
函數(shù)中,沒有 var 聲明的變量都是全局變量,而且并不會(huì)提前聲明。

作用域鏈

作用域鏈:內(nèi)部函數(shù)訪問外部函數(shù)的變量,采用的是鏈?zhǔn)讲檎业姆绞絹?lái)決定取哪個(gè)值,這種結(jié)構(gòu)稱之為作用域鏈。查找時(shí),采用的是就近原則。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容