做用域是指一段代碼的有效範圍,在JavaScript中分爲全局做用域和局部做用域。全局做用域值得是global對象(window對象),局部做用域則是在全局下的函數或對象的做用域。局部做用域能夠訪問全局做用域,而全局做用域不能夠訪問局部做用域。數組
上下文,JavaScript使用了上下文的概念對應着做用域。函數
執行上下文: 全局上下文、 局部上下文this
建立一個上下文:spa
1. 準備code
建立新的做用域對象
建立變量、函數和參數blog
肯定this關鍵字的值ip
2. 執行作用域
如今能夠給變量賦值io
引用函數來執行其代碼
執行語句
在準備階段先建立一個variables對象,保存了上下文中的變量、函數和參數,在variables對象先建立一個arguments數組存放傳過來的參數,而後在建立上下文中函數屬性(將上下文中函數做爲variables對象的屬性),最後存放變量屬性。執行階段,執行函數體中的代碼,一行一行地運行代碼,給variables對象中的變量屬性賦值。
第一個建立全局上下文,將全局上下文放在棧頂部,優先執行。當執行上下文時,最早執行函數,這時會建立函數的上下文,並將其頂到棧頂,由於在棧頂優先處理的元素,因此同名變量中局部做用域比全局做用域優先級要高。
(function(){ console.log(typeof foo); //function console.log(typeof bar); //undefind var foo = 'hello'; var bar = function(){ return 'world'; } function foo(){ return 'hello'; } })()
由於準備階段查詢上下文並建立variables對象的屬性,因此只是建立了這些變量並無賦值。可是函數foo()是能夠執行,說明函數的建立在建立這些屬性以前。執行階段,每次賦值就會覆蓋掉這些屬性。