作用域
變量或函數(shù)可以發(fā)生作用的區(qū)域即是作用域搏屑。
作用域的最大用途就是隔離變量或函數(shù),并控制變量或函數(shù)的生命周期免胃,超過該區(qū)域的變量或函數(shù)就不能被訪問音五。
js變量(不包括函數(shù))的作用域是函數(shù)級的,也就是說定義變量的整個函數(shù)區(qū)域都可以訪問到它羔沙,即使這個變量是否定義在while躺涝、if代碼塊中也可以。就像我們上面的例子扼雏,j是定義在代碼塊中的坚嗜,然而在代碼塊外也可以訪問到。
全局作用域
1诗充、在最外層定義的變量和函數(shù)擁有全局作用域苍蔬。
2、未聲明直接賦值的變量擁有全局作用域蝴蜓。
3碟绑、在瀏覽器中,定義在window對象上的屬性和方法茎匠,擁有全局作用域蜈敢。
函數(shù)作用域
在某個函數(shù)內(nèi)部聲明的變量或函數(shù)擁有函數(shù)作用域。它們只能被該函數(shù)的語句使用汽抚,函數(shù)外部是不可訪問的。函數(shù)在創(chuàng)建的時候伯病,變量和函數(shù)的函數(shù)作用域已經(jīng)確定下來造烁。函數(shù)的參數(shù)也屬于函數(shù)內(nèi)部的變量,因此擁有函數(shù)作用域午笛。
例子:
第一段代碼是在函數(shù)中找到a變量惭蟋,第二段代碼是在全局中找到b變量。現(xiàn)在閉上眼睛药磺,我要給加粗的這兩個詞的后面加上幾個字了告组!
好了,打開眼睛癌佩,Duang木缝,Duang --->函數(shù)作用域便锨、全局作用域,把這兩個詞換入到原來那句話中我碟,第一段代碼是在函數(shù)作用域中找到a變量放案,第二段代碼是在全局作用域中找到b變量。
我們在查找b變量的時候矫俺,先在函數(shù)作用域中查找吱殉,沒有找到,再去全局作用域中查找厘托,有一個往外層查找的過程友雳。我們好像是順著一條鏈條從下往上查找變量,這條鏈條铅匹,我們就稱之為作用域鏈押赊。
查找變量也是順著紅色的箭頭走的,從里到外伊群,這從里到外的各層作用域就組成了作用域鏈考杉。
詞法作用域:函數(shù)的作用域在函數(shù)定義的時候就決定了。與詞法作用域相對的是動態(tài)作用域舰始。
動態(tài)作用域:函數(shù)的作用域是在函數(shù)調(diào)用的時候才決定的崇棠。
執(zhí)行上下文.變量對象(Variable Object)
1、確定?this?的值丸卷,也被稱為?This Binding枕稀。
2、LexicalEnvironment(詞法環(huán)境)?組件被創(chuàng)建谜嫉。用于存儲函數(shù)聲明和變量(?let?和?const?)綁定
3萎坷、VariableEnvironment(變量環(huán)境)?組件被創(chuàng)建。僅用于存儲變量(?var?)綁定
詞法環(huán)境有兩個組成部分
1沐兰、環(huán)境記錄:存儲變量和函數(shù)聲明的實際位置
2哆档、對外部環(huán)境的引用:可以訪問其外部詞法環(huán)境
變量環(huán)境
變量環(huán)境也是一個詞法環(huán)境
變量提升的原因:在創(chuàng)建階段,函數(shù)聲明存儲在環(huán)境中住闯,而變量會被設置為undefined(在?var?的情況下)或保持未初始化(在?let?和const?的情況下)瓜浸。所以這就是為什么可以在聲明之前訪問?var?定義的變量(盡管是?undefined?),但如果在聲明之前訪問?let?和?const定義的變量就會提示引用錯誤的原因比原。這就是所謂的變量提升插佛。