最近跳槽季,刷面試,被問到的問題,答不出或以爲答的很差,底下查找資料學習下,順便整理一下,跟你們一塊兒學習!web
1、event loop事件循環及線程問題面試
其實二者是有關聯的。就由於JS是單線程,因此全部的任務就得排隊執行,js代碼始終在一個線程上執行,此線程被稱爲js引擎線程。(爲何單線程,舉別人舉的例子:假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另外一個線程刪除了這個節點,這時瀏覽器應該以哪一個線程爲準?),前一個任務結束,纔會執行後一個任務。瀏覽器
說到任務,也分同步和異步任務。全部的同步任務在主線程排隊執行,造成一個執行棧。異步任務會被主線程掛起,不會進入主線程,而是進入消息隊列,也叫任務隊列或事件隊列。隊列都是先進先出,最早進入的任務最早執行。同時,異步任務須要指定回調函數,一個異步過程包括兩個要素:註冊函數和回調函數,其中註冊函數用來發起異步過程,回調函數用來處理結果。多線程
js是單線程而瀏覽器是多線程閉包
一下一張來自網上的圖,大體有如下線程app
一、ui渲染線程主要用來渲染頁面。(js能夠操做dom,影響渲染,因此js引擎線程和UI線程是互斥的。js執行時會阻塞頁面的渲染。)dom
二、js引擎線程,即上面說的單線程異步
異步任務須要瀏覽器執行事件觸發線程或定時器觸發線程或http請求線程,因此異步是瀏覽器的兩個或者兩個以上線程共同完成的。ide
瞭解了以上,咱們來講下event loop事件循環函數
詳細步驟以下:
一、全部同步任務都在主線程上執行,造成一個執行棧
二、主線程以外,還存在一個"消息隊列"。只要異步操做執行完成,就到消息隊列中排隊
三、一旦執行棧中的全部同步任務執行完畢,系統就會按次序讀取消息隊列中的異步任務,因而被讀取的異步任務結束等待狀態,進入執行棧,開始執行
四、主線程不斷重複上面的第三步
因爲主線程不斷的重複得到消息、執行消息、再取消息、再執行。因此,這種機制被稱爲事件循環
實例說明:
console.log(1) div.onclick = () => {console.log('click')} console.log(2) setTimeout(() => {console.log('timeout')},1000)
一、執行第一行代碼,第一行是一個同步任務,控制檯顯示1
二、執行第二行代碼,第二行是一個異步任務,發起異步請求,能夠在任意時刻執行鼠標點擊的異步操做
三、執行第三行代碼,第三行是一個同步任務,控制檯顯示2
四、執行第四行代碼,第四行是一個異步任務,發起異步請求,1s後執行定時器任務
五、假設從執行第四行代碼的1s內,執行了鼠標點擊,則鼠標任務在消息隊列中排到首位
六、從執行第四行代碼1s後,定時器任務到消息隊列中排到第二位
七、如今同步任務已經執行完畢,則從消息隊列中按照次序把異步任務放到執行棧中執行
八、則控制檯依次顯示'click‘、'timeout'
九、過了一段時間後,又執行了一次鼠標點擊,因爲消息隊列中已經空了,則鼠標任務在消息隊列中排到首位
十、同步任務執行完畢後,再從消息隊列中按照次序把異步任務放到執行棧中執行
十一、 則控制檯顯示'click'
2、this指向問題
this 指的是當前對象,若是在全局範圍內使用this,則指代當前頁面window;若是在函數中使用this,則this指代什麼是根據當前函數是在什麼對象上調用。函數中的this是在運行時候決定的,而不是函數定義時。可使用call和apply改變函數中this的具體指向。
function dog(){ console.log(this.name); } var name = "哈士奇"; dog(); //哈士奇 var o = { name: "金毛" }; dog.call(o); //金毛
3、瀏覽器內核
瀏覽器的內核的不一樣對於網頁的語法解釋會有不一樣,因此渲染的效果也不相同。一般最開始渲染引擎和 JS 引擎並無區分的很明確,後來 JS 引擎愈來愈獨立,內核就傾向於只指渲染引擎。常見的瀏覽器內核有:Trident(IE內核)、Gecko(Firefox 內核)、谷歌Blink內核、weblit內核
4、margin-top/top的百分比是相對於父元素的寬度計算的。
5、彈性佈局的瞭解
6、閉包