執行期上下文(AO):函數在運行時(或預編譯時),會建立一個叫執行期上下文問的一個內部對象Activation Object(全局的叫Global Object)。AO或GO,他定義了一個函數的執行環境(用來作變量/函數的提高等等),函數執行完畢則會銷燬。es6
做用域:每個函數對象都有一個[[scope]]屬性,他內部存儲了執行期上下文的集合,也就是咱們說的做用域。這個集合是一種鏈式結構,叫作做用域鏈bash
舉個栗子:函數
function a(){
function b(){
var b = 123
}
var a = 10
b()
}
var glob = 100
a()
複製代碼
1.a函數定義時,它的[[scope]]會指向它的上一級即全局的執行期上下文(GO) ui
全局做用域:全局做用域指的是在全局起做用的做用域。通常指上面所說的GOthis
局部做用域(函數做用域):局部做用域指的是在局部起做用的做用域。通常函數的做用域都是局部做用域,即上面的AO。es5
塊做用域:通常而言,塊做用域指的是以{}包含的內容快,函數或變量只在它所在的的快內起做用。es5中不存在塊做用域,es6新增了塊做用域。for循環和if語句的{}屬於塊做用域spa
舉個例子 當咱們使用if語句時,在if語句的內部定義了變量3d
var foo = true
if(foo){
var c = 2
console.log(c) // 2
}
console.log(c) // 2
複製代碼
變量c只在if所在的代碼塊中使用,所以將他聲明在if語句內部是很必要的,可是經過var聲明的變量最終都會屬於外部做用域。至關於如下代碼code
var foo = true
var c
if(foo){
c = 2
console.log(c) // 2
}
console.log(c) // 2
複製代碼
因此就須要一些其餘的結構或語法來實現塊級做用域。在es6中新增了let/const,用來聲明變量 let會把變量綁定在它所在的塊中。 const用來聲明常量,也會造成塊級做用域。cdn
var foo = true
if(foo){
let c = 2
console.log(c)
}
console.log(c) // 報錯
複製代碼
因爲let會造成塊級做用域,因此if(){}外接受不到c變量,因此會報錯