作用域,變量的作用范圍
在ES6之前
變量的聲明
只有var可以聲明變量屬于某個作用域,并且,也只有全局作用域和函數(shù)作用域。(沒有var聲明的變量,屬于全局作用域,在全局作用域里聲明的變量,函數(shù)會成為全局的屬性)
所有的變量,不是全局作用域的,就是函數(shù)作用域的。
如果用var 聲明變量,并且是在函數(shù)中,那么這個變量就屬于這個函數(shù),否則,屬于全局變量。
提升
在JavaScript的任何一個作用域中,都存在提升;
對于一個聲明var a=2;引擎主要會分兩步走,var a; a=2; JS引擎進行處理和執(zhí)行。
所謂的處理,引擎首先會進行全局的掃描,遇到變量的聲明(var 聲明的變量)就會記錄,遇到函數(shù)聲明(function 關鍵字開頭)也會進行記錄,直到全局掃描完畢。然后,引擎開始從頭執(zhí)行,對變量進行修改,對函數(shù)進行調(diào)用。
上邊所謂的記錄,就是提升行為。(如果學過C語言,就知道,函數(shù),變量都要先定義,在使用,否則會報錯,但是,js提升,可以理解為,不管你定義在哪里,都會被提升到使用的前面,也就是可以把使用寫在定義前面)
引擎會把聲明的變量,函數(shù)聲明記錄到全局的作用域,記錄有哪些變量存在,并對變量進行初始化賦值,undefined;為什么是記錄到全局,而不是對應作用域,主要是因為,一開始掃描,就是掃描全局作用域,它只掃描一級, 它不會深入掃描,只掃描表面。這個其實很好理解,除了變量的提升,還有函數(shù)聲明的提升,遇到function 關鍵字,js引擎只是簡單的將其提升到最頂層,在全局作用域中定義的函數(shù),它作用域就相當于二級,js引擎是不會在這個時候去掃描函數(shù)作用域的。
例如: