js篇
call,apply,bind
call,apply,bind這三者的區別,及內部實現原理,點這裏
promise
promise函數的內部實現原理
異步與事件輪詢機制
JavaScript語言的核心特點就是單線程,單線程的原因主要是對DOM的操作,多線程操作DOM會引起衝突。爲了利用多核CPU的計算能力,HTML5提出了web worker標準,允許JavaScript創建多線程,且創建線程完全受主線程控制,且不得操作DOM。
js的異步是通過回調函數實現的,即任務隊列。雖然js是單線程的,但瀏覽器的多線程的,則js的執行遇到異步任務都會調用瀏覽器的多線程去執行,當異步任務有了結果,則會將異步任務的回調函數放入異步任務隊列。
任務隊列分爲兩種:宏任務隊列與微任務隊列。
當js從上往下執行時,如遇到異步任務,瀏覽器則用其他線程去執行,當異步任務有了結果,則將回調函數放到任務隊列中,當主執行棧執行完後,會去查詢微任務隊列,如果有則執行,微任務隊列執行完後,則將宏任務隊列放入主執行棧重新開始下一輪循環。
不同的js異步API的回調函數放入不同的任務隊列。
宏任務(macrotask)隊列API:
- setTimeout
- setInterval
- setImmediate(node)
- requestAnimationFrame(js)
微任務(microtask)隊列API:
- process.nextTick(node)
- MutationObserver(node)
- Promise.then catch finally
注意的一點:微任務隊列中的微任務回調函數是放入當前微任務隊列中,而不是下輪循環隊列。
瀏覽器垃圾回收機制
標記清除
垃圾收集器給內存中的所有變量都加上標記,然後去掉環境中的變量以及被環境中的變量引用的變量的標記。在此之後再被加上的標記的變量即爲需要回收的變量,因爲環境中的變量已經無法訪問到這些變量。
引用計數
js執行上下文和執行棧
該點的解釋則是表明JavaScript程序內部的執行機制。
執行上下文,簡而言之,就是當前JavaScript代碼被解析和執行時所在環境的抽象概念,JavaScript任何代碼都是在執行上下文中運行。
三種類型:
- 全局執行上下文:不在任何函數內的代碼都處於全局執行上下文,一個程序只能有一個全局執行上下文。做了兩件事:1、創建了一個全局對象,瀏覽器則是window;2、將this指向這個全局對象。
- 函數執行上下文:每個函數都有自己的執行上下文。調用函數時,都會爲這個函數創建一個新的執行上下文,也只在函數被調用時纔會被創建。一個程序內的函數執行上下文沒有數量限制,每當一個函數執行上下文被創建,則會執行一系列操作。
- eval函數執行上下文:不常用,略。
生命週期:
- 創建:創建變量對象,創建作用域鏈,確定this指向(this的賦值是在執行的時候確定的)。
- 執行:變量賦值,代碼執行。
- 回收:執行完成,執行上下文出棧,等待回收。
管理執行上下文:
所有的執行上下文采用的是棧結構來管理,遵循先進後出。全局JavaScript代碼在瀏覽器執行時,實現創建一個全局執行上下文,壓入執行棧的底端,每創建一個函數執行上下文,則把它壓入執行棧的頂端,等待函數執行完,該函數的執行上下文出棧等待回收。
JavaScript解析引擎總是訪問執行棧的頂端,當瀏覽器關閉,則全局執行上下文出棧。
url輸入到頁面顯示之間的過程
- 用戶輸入的url作DNS解析,獲取IP地址
- 建立TCP連接
- 發送HTTP請求,獲取html文件
- 解析HTML文件,構建DOM樹及CSSOM規則樹,然後合併渲染樹,繪製界面。
- 發送HTTP獲取HTML文件內其他資源。
new操作符中的執行過程
nodejs篇