目錄:
DOM事件流有那些階段?
通常,我們將DOM事件流向分為三個階段:捕獲階段,目標階段,冒泡階段。
- 捕獲階段是指事件響應從最外層的Window開始,逐級向內層前進,直到具體事件目標元素。在捕獲階段,不會處理響應元素注冊的冒泡事件。
- 目標階段指觸發事件的最底層的元素。
- 冒泡階段與捕獲階段相反,事件的響應是從最底層開始一層一層往外傳遞到最外層的Window。
解釋事件冒泡以及如何阻止它?
事件由具體的dom節點接收,然后這個事件順着嵌套順序在父元素上觸發。
防止事件冒泡的一種方法是使用 event.stopPropagation()或 event.cancelBubble (低於 IE 9)。
事件委派/事件委托是什么?
事件委派/事件委托適用於未來的元素(動態添加的元素)
利用事件冒泡,將后代元素上事件的處理程序委派給祖先元素。
參考:事件委派的使用及作用
如何理解 JS 中的this關鍵字?
上下文環境:全局上下文、函數上下文
- 全局函數:this 指向 window 對象
- 作為對象的方法:當函數作為對象的方法調用時,它的
this
值是調用該函數的對象。(箭頭函數除外) - 作為構造函數:函數作為構造函數,那函數當中的 this 便 new 出來的對象
- 函數調用 apply、call、 bind 時: this 的值就取傳入對象的值 (與 apply、call 不同,使用 bind 只會改變一次this的值,無論之后怎么調用)
- 箭頭函數:this 的值與創建箭頭函數的上下文的 this 一致
也可以用簡潔的方式來回答:
- ES5中:this 永遠指向最后調用它的那個對象
- ES6箭頭函數:箭頭函數的 this 始終指向函數定義時的 this,而非執行時。
更改this指向的方法有那些?
- 使用 ES6 的箭頭函數
- 在函數內部使用 _this = this
- 使用 apply、call、bind
- new 實例化一個對象
apply、call、bind 區別?
apply 和 call 的區別
其實 apply 和 call 基本類似,他們的區別只是傳入的參數不同。
call 的參數是直接放進去的,第二第三第 n 個參數全都用逗號分隔,直接放到后面
apply 的所有參數都必須放在一個數組里面傳進去
bind與apply、call最大的區別就是:bind不會立即調用,其他兩個會立即調用
參考:JavaScript 中 call()、apply()、bind() 的用法、更改this指向的方法及其區別
講講JavaScript 作用域
全局作用域:定義在所有函數之外的變量,其作用范圍是在整個腳本中
局部作用域(函數作用域):使用var定義在函數內部的變量,其作用范圍是整個函數結構,超出函數 {} 花括號的范圍則不能使用。
塊級作用域:ES6聲明變量的方式:let / const 在變量聲明的代碼段之外是不可見的
參考:JS作用域與聲名提升
js函數聲明三種方式
//(1) Function()構造器 var f =new Function() //(2) 函數聲明 function f (){ console.log(2); } //(3) 函數表達式 var f = function() { console.log(1); }
參考:1-1 聲明
js變量聲明
var、let、const
var聲明的變量會掛載在window上,而let和const聲明的變量不會
var聲明變量存在變量提升,let和const不存在變量提升(嚴格來說,let也存在)
let和const聲明形成塊作用域存在暫存死區
const聲明必須賦值
參考:1-1 聲明 、較詳細的:JS聲明變量的六種方式
拓展:如果用 const 聲明一個對象,改變對象中某個屬性的值會發生什么?
如圖:
為什么 對象中的b的值變了?如果換成直接給 a={b:3}可以嗎?
為什么會報錯?
const
實際上保證的,並不是變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。
const
只能保證這個指針是固定的(即總是指向另一個固定的地址),至於它指向的數據結構是不是可變的,就完全不能控制了。
JS的數據類型有哪些?
基本類型:
- string(字符串)--原始類型
- boolean(布爾值)--原始類型
- number(數字)--原始類型
- symbol(符號)--原始類型
- null(空值)undefined(未定義)
- BigInt(BigInt數據類型的目的是比Number數據類型支持的范圍更大的整數值,精度在(2^53-1)范圍內,BigInt(10)值為:10n)
對象類型(引用類型):Array - - (數組)、Function - - (函數)、Date - - (時間)等
參考:1-2 數據類型的分類:、JavaScript的數據類型詳細介紹
如何判斷JS變量的數據類型?
typeof:只能判斷string、boolean、number、null、symbol
instanceof:判斷對象類型:測試構造函數的 prototype 是否出現在被檢測對象的原型鏈上
延展:為什么typeof null為object?
js 在底層存儲變量的時候,會在變量的機器碼的低位1-3位存儲其類型信息,而 000代表對象,null的所有機器碼均為0,所以,typeof 在判斷 null 的時候就出現問題了,由於null 的所有機器碼均為0,因此直接被當做了對象來看待。
參考:1-3 數據類型的判斷:
什么是閉包?
閉包指的是能夠訪問另一個函數作用域的變量的函數。
閉包就是一個函數,這個函數能夠訪問其他函數的作用域中的變量。
閉包經典理解
- 由於var 變量的提升,循環的時候賦值都是用一個i;
- 因為setTimeout為宏任務,由於JS中單線程eventLoop機制,在主線程同步任務執行完后才去執行宏任務,因此循環結束后 才執行setTimeout,但輸出i的時候當前作用域沒有,往上一級再找,發現了i,此時循環已經結束,i變成了10;
- 使用let可以解決 let形成塊級作用域不會提升
for (var i = 0; i < 10; i++) { //這個時候 i已經 = 10了 var i提升 每次進行賦值都是同一個i; setTimeout(() => { console.log(i);// 打印10個10 }, 1000) }
「使用閉包 」
for (var i = 0; i < 10; i++) { ((i) => { setTimeout(() => { console.log(i);//打印0-9 }, 1000) })(i) }
優點:避免全局變量的污染、希望一個變量長期存儲在內存中(緩存變量)
缺點:內存泄露(消耗)、常駐內存,增加內存使用量
參考:4 閉包、閉包到底是什么?、閉包的概念?優缺點?、破解前端面試(80% 應聘者不及格系列):從閉包說起
談談你對JavaScript原型,原型鏈的理解
prototype:構造函數的原型對象
原型鏈:JS在創建對象的時候,會在新對象上產生一個__proto__的屬性,這個屬性指向了它構造函數的原型的prototype。由此一級一級向上直到到達Object.prototype.proto === null的這個鏈條我們稱之為原型鏈。
談談你對面向對象編程思想的理解,它有什么特點?
面向對象編程是一種解決軟件復用的設計和編程方法。 這種方法把軟件系統中相近相似的操作邏輯和操作 應用數據、狀態,以類的型式描述出來,以對象實例的形式在軟件系統中復用,以達到提高軟件開發效率的作用。
面向對象的理解:
面向對象是一種設計思想
- 符合人們的思考習慣
- 把執行者變成指揮者
- 簡化功能,把復雜的事情簡單化
什么是封裝?
類是一種封裝,將屬性和方法封裝。
函數也是一種封裝,將具有一定共的邏輯代碼封裝到一個函數中,使用的時候調用即可
什么是繼承?
js 執行機制、事件循環
同步和異步任務分別進入不同的執行"場所",同步的進入主線程,異步的進入 Event Table 並注冊函數。當指定的事情完成時,Event Table 會將這個函數移入 Event Queue。主線程內的任務執行完畢為空,會去 Event Queue 讀取對應的函數,進入主線程執行。上述過程會不斷重復,也就是常說的 Event Loop(事件循環)。
主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為 Event Loop(事件循環)。只要主線程空了,就會去讀取"任務隊列",這就是 JavaScript 的運行機制。
參考:js 執行機制、事件循環
拓展:宏任務、微任務
宏任務:整體代碼 script,setTimeout,setInterval
微任務:Promise,process.nextTick
我們知道setTimeout這個函數,是經過指定時間后,把要執行的任務(本例中為task())加入到Event Queue中,又因為是單線程任務要一個一個執行,
如果前面的任務需要的時間太久,那么只能等着,導致真正的延遲時間遠遠大於你定義的延時時間。https://juejin.cn/post/6844903512845860872#heading-1
我們還經常遇到setTimeout(fn,0)這樣的代碼,0秒后執行又是什么意思呢?是不是可以立即執行呢?
答案是不會的,setTimeout(fn,0)的含義是,指定某個任務在主線程最早可得的空閑時間執行,意思就是不用再等多少秒了,只要主線程執行棧內的同步任務全部執行完成,棧為空就馬上執行。
同步和異步的區別?
異步:客戶端與服務器請求數據的過程中,可以做其他的事情
同步:客戶端與服務器請求數據的過程中,不能做其他的事情
參考:同步和異步的區別?
對前端性能優化有什么了解?一般都通過那幾個方面去優化的?
前端性能優化的七大手段
- 減少請求數量
- 減小資源大小
- 優化網絡連接
- 優化資源加載
- 減少重繪回流
- 性能更好的API
- webpack優化
參考:對前端性能優化有什么了解?一般都通過那幾個方面去優化的?
JavaScript的數組的常用方法
向數組添加元素的方法:
- Array.push:向數組的末尾追加 返回值是添加數據后數組的新長度,改變原有數組
- Array.unshift:向數組的開頭添加 返回值是添加數據后數組的新長度,改變原有數組
- splice:向數組的指定index處插入 返回的是被刪除掉的元素的集合,會改變原有數組
向數組刪除元素的方法:
- pop():從尾部刪除一個元素 返回被刪除掉的元素,改變原有數組
- shift():從頭部刪除一個元素 返回被刪除掉的元素,改變原有數組
- splice:在index處刪除howmany個元素 返回的是被刪除掉的元素的集合,會改變原有數組
數組排序的方法:
- everse():反轉,倒置 改變原有數組
- sort():按指定規則排序 改變原有數組
參考:JavaScript的數組的常用方法(一)、js常用數組方法
持續更新呦!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!