1.事件輪詢?
- JavaScript 是單線程的,同一時間只能做一件事。所有任務都需要排隊,前一個任務結束,才會執行后一個任務,為了保證任務有序的執行,事件輪詢就是單線程任務調度的一種方式,單線程任務分為同步任務和異步任務,而異步任務又分為宏任務和微任務
- 過程: 瀏覽器會首先執行宏任務, 如果執行過程中,遇到宏任務,就把他加入宏任務隊列,遇到微任務,就把他加入微任務隊列,當前宏任務執行完后,會判斷 微任務列表 中是否有任務,如果有,執行微任務,當所有微任務執行完后,再執行下一個宏任務,不斷循環。
- 宏任務:主代碼塊、setTimeOut、setInterval、script、I/O操作、UI渲染
- 微任務:promise、async/await(返回的也是一個promise)、process.nextTick
2.Hash和history的區別?
???????hash與history一般指前端框架中的路由模式,對應兩種路由 hash路由和history路由
- hash路由兼容性比histroy路由好
- 瀏覽器url中hash 路由帶了一個很丑的 #,而history是沒有的
- hash即瀏覽器地址欄 URL 中的 # 符號,hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,因此改變 hash 不會重新加載頁面
- history利用了 HTML5新增的 pushState() 和 replaceState() 方法,在已有 back()、forward()、go() 的基礎上,提供了對歷史記錄進行修改的功能。調用pushState() 和 replaceState()時,雖然改變了當前的 URL,但瀏覽器不會向后端發送請求,但如何用戶刷新頁面,會導致瀏覽器向服務器發起請求,如后端沒有做出適當的響應,則會顯示404頁面
3.強緩存和協商緩存?
- 瀏覽器緩存主要分為強緩存(也稱本地緩存)和協商緩存(也稱弱緩存)。
- 瀏覽器在第一次請求發生后,再次發送請求時
- 強緩存:瀏覽器請求某一資源時,會先獲取該資源緩存的header信息,然后根據header中的Cache-Control和Expires來判斷是否過期。若沒過期則直接從緩存中獲取資源信息,包括緩存的header的信息,所以此次請求不會與服務器進行通信。這里判斷是否過期,則是強緩存相關。
- 協商緩存:協商緩存就是由服務器來確定緩存資源是否可用,所以客戶端與服務器端要通過某種標識來進行通信,從而讓服務器判斷請求資源是否可以緩存訪問。主要看響應頭的Etag和last-modify這兩個字段.
- 強緩存狀態碼200,協商緩存304.
4.url過程?
- URL解析:當在瀏覽器地址欄輸入URL后,瀏覽器會判斷這個URL的合法性,以及是否有可用緩存。如果判斷是URL則進行域名解析,如果不是URL,則直接使用搜索引擎搜索。
- 域名解析:瀏覽器首先會解析域名,獲取對應的IP地址。這個過程涉及到了域名解析服務器的查詢和轉發,如果本地DNS緩存中有對應的條目,則可以直接使用緩存的IP地址。
- TCP連接:獲取到IP地址后,瀏覽器便會與服務器建立TCP連接,包括客戶端向服務器發送SYN(同步)報文,服務器回復SYN+ACK(同步/應答)報文,最后客戶端再回復ACK(應答)報文,完成三次握手過程。
- 發送HTTP請求:TCP連接建立后,瀏覽器便會向服務器發送HTTP請求報文,其中包括請求方法、路徑、協議版本等信息,以及請求頭部信息等。
- 服務器響應:服務器接收到請求后,會從服務器文件系統或者處理邏輯中獲取到數據,生成HTTP響應報文,并將其返回給瀏覽器。
- 瀏覽器渲染:當瀏覽器接收到響應報文后,會對HTML文檔進行解析,并構建dom樹、css樹、渲染樹等,最終將頁面呈現給用戶。
- 連接關閉:當瀏覽器從服務器接收到所有需要的數據后,就會關閉TCP連接。
5.瀏覽器渲染過程?
- 解析html,瀏覽器首先解析HTML文檔,將其轉化為dom樹。這個過程中,瀏覽器會將HTML標簽轉化為節點,形成DOM樹的結構。
- 解析CSS。瀏覽器解析CSS文件,構建css樹。CSS樹是包含所有CSS樣式信息的樹結構。
- 構建渲染樹。將DOM樹和CSSOM樹合并,形成渲染樹。渲染樹只包含那些需要顯示在頁面上的元素,并且每個元素根據CSSOM包含了相應的樣式信息。
- 布局計算。根據渲染樹的結構,計算每個節點在屏幕上的大小、位置等屬性,生成布局信息。這個過程涉及到元素的尺寸和位置的計算,可能會發生回流和重繪。
- 頁面繪制。將生成的布局信息交給瀏覽器的繪圖引擎,通過GPU加速將像素繪制到屏幕上。這一步將布局信息轉化為實際的視覺展示。
- 執行JavaScript代碼。瀏覽器的主線程負責解析和執行JavaScript代碼。如果JavaScript代碼修改了DOM,這可能會影響渲染樹的構建和頁面的繪制。
6.script腳本的異步加載順序?
- script有兩種異步加載方式 ?分別是defer與async
- defer與async的區別是:
- defer要等到整個頁面在內存中正常渲染結束(DOM 結構完全生成,以及其他腳本執行完成),才會執行;
- async一旦下載完,渲染引擎就會中斷渲染,執行這個腳本以后,再繼續渲染。
- 一句話,defer是“渲染完再執行”,async是“下載完就執行”。
- 另外,如果有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。
7.ES6模塊化和commonjs模塊化區別?
- 語法不同:ES Module使用import導入,export或者export default導出,CommonJS使用require導入,exports導出
- 加載時機不同:ES Module是編譯時加載,代碼執行前,靜態分析階段,使用import函數時是運行時加載,CommonJS是運行時加載,必須等模塊內所有代碼運行結束后才能導出
- 加載方式不同:ES Module是異步加載,不會阻塞代碼,CommonJS是同步加載,如果加載的模塊夠大時,可能會阻塞后續代碼
- 導出方式不同:ES Module是導出值的引用,多個文件引入同一個模塊得到的引用是同一個,CommonJS是值的拷貝
- 效率不同:ES Module加載效率更高,編譯時加載、模塊緩存機制、并行加載、tree-shaking,CommonJS效率相對較低
- 導出的內容不同:ES Module是編譯階段靜態分析,導出靜態定義,所以很多ES Module模塊化的優化都是在這?? ?個階段做的,這也就是ES Module能夠更好的支持tree shaking的原因,CommonJS導出的是對象,必須加載完模塊內的所有代碼才能生成導出對象,導致commonjs?? ?不好優化
- ES Module導出的變量是只讀的不能修改,修改了會報錯,CommonJS導出的變量是可以修改的,這是因為ES Module導出的是引用,如果可修改會影響其他模塊的導入,commonjs導出的是值的拷貝,不會影響
8.es6新特性?
- class 類
- let、const變量聲明方式
- 新增了promise異步
- 新增了symbol基本數據類型
- 新增了proxy (代理)Api
- 新增了set、map數據結構
- es6模塊化
- 新增了箭頭函數
- 新增了模板字符串
- 新增了...擴展運算符
- 新增了生成器函數
- for...of循環
9.for....in.... 和 for....of.... 的區別?
- 遍歷對象時:for…of 遍歷獲取的是對象的鍵值,for…in 獲取的是對象的鍵名;?
- 遍歷數組時:for…of 只返回數組的下標對應的屬性值,for…in 會返回數組中所有可枚舉的屬性(包括原型鏈上可枚舉的屬性),
- 總的來說for...in適合遍歷對象,for...of適合遍歷數組等可迭代的數據類型(數組、字符串等)
10.原型和原型鏈?
- 原型:構造函數的prototype屬性,它的屬性值是一個對象,這個對象包含了可以由該構造函數的所有實例共享的屬性和方法。
- 原型鏈:當訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那么它就會去它的原型對象里找這個屬性,這個原型對象又會有自己的原型,于是就這樣一直找下去,這種鏈狀結構就叫做原型鏈
? ??
? ??