函數每一次調用就會產生一個新的執行上線文環境,它被放在執行上下文棧。變量或函數的上下文決定了它們能夠訪問哪些數據,以及它們的行爲。執行上下文棧會在其全部代碼執行完畢把執行上下文彈出,將控制權返回給執行上下文。ECMAScript代碼執行流就是經過執行上下文棧進行控制。前端
1.全局執行上下文是最外層的上下文,在瀏覽中全局上下文就是window對象。JavaScript代碼運行起來會首先進入該環境,棧底永遠都是全局上下文,而棧頂就是當前正在執行的上下文。
2.函數執行上下文
3.eval執行上下文ide
1.變量對象,每一個上下文都有一個變量對象,這個上下文內定義的全部變量和函數都存在這個對象上,可是沒法經過代碼訪問這個變量對象,但在後臺會用到它。
2.做用域鏈,在執行上下文代碼執行的時候,建立做用域鏈,做用域鏈決定執行上下文代碼在訪問變量和函數的順序,權利。
3.this,函數
建立-> 執行 -> 回收
1.建立
(1)建立做用域鏈(Scope Chain)。
(2)建立變量對象(函數的形參、函數聲明、變量聲明)。
(3)求」this「的值。
2.執行
代碼執行
3.回收
執行上下文出棧被垃圾回收機制進行回收。學習
1.try/catch語句的catch塊
2.with語句
catch語句會建立新的變量對象,with語句會向做用域前段添加指定的對象。this
1.var:函數做用域,聲明會被拿到函數或做用域頂部,這個現象叫提高(hoisting)code
2.let:塊級做用域即爲{聲明內},if,while,function都是塊,它不能在同一做用域聲明屢次,而var會被忽略。let也會被提高,可是約束了變量提高。對象
暫時性死區:當程序的控制流程在新的做用域(module
function
或 block
做用域)進行實例化時,在此做用域中用let/const聲明的變量會先在做用域中被建立出來,但所以時還未進行詞法綁定,因此是不能被訪問的,若是訪問就會拋出錯誤。所以,在這運行流程進入做用域建立變量,到變量能夠被訪問之間的這一段時間,就稱之爲暫時死區( temporal dead zone),簡稱 TDZ)。生命週期
3.const:不能從新複製,因此必須初始化,暗示變量的值是單一類型且不可修改。能夠用Object.freeze()讓整個對象都不能修改。ip
聲明變量會自動添加到最接近的上下文,若是未經聲明就初始化,將自動添加到全局上下文原型鏈
console.log(a)//undefined console.log(b)//報錯,暫時性死區 var a = 3; let b = 4;`
let a = 'outside'; if(true) { console.log(a);//Uncaught ReferenceError: a is not defined let a = "inside"; }//a報錯沒有定義,因此let有變量提高,可是因爲死區咱們沒法在聲明前訪問這個變量
當上下文要讀取或寫入一個標識符時,必須肯定標識符是什麼,搜索開始與做用域鏈最前端,若是沒有找到變量名,繼續沿着做用域鏈搜索。(做用域鏈中對象可能原型鏈,所以搜索可能涉及原型鏈),最後一直搜索到做用域鏈底部(全局上下文)
let name = 'a' function getName(){ let name = 'b' { let name = 'c' return name } } console.log(getName());//c,塊級做用域不會更改搜索流程,可是能夠增長額外層次
標識符查找也有代價,須要後臺處理,訪問最近的局部變量更快,由於不用切換做用域搜索。
小白,想系統的學習JavaScript,看的大佬文章,書,記錄一下學習的內容。否則總是忘記誒。但願你們多給點建議,指點指點錯誤啥的哈哈