JS方面
備註: + 代表被問到的次數,沒有 + 代表自己整理了,但沒被問到
1.js繼承的方式+
- 原型鏈繼承
- 借用構造函數繼承(通過call()實現)
- 組合繼承(原型+借用構造)
- 通過ES6中class的extends關鍵字實現繼承
2.NEW操作符做了那些事情+
- 創建一個新對象;
- 將構造函數的作用域賦給新對象(因此this就指向了這個新對象);
- 執行構造函數中的代碼(爲這個新對象添加屬性);
- 返回新對象
3.call/aplay的區別++
作用:動態改變某個類的某個方法的運行環境(執行上下文)
- call可以傳入多個參數;
- apply只能傳入兩個參數,所以其第二個參數往往是作爲數組形式傳入
4.this指向哪裏?+
JavaScript this 關鍵詞指的是它所屬的對象。
它擁有不同的值,具體取決於它的使用位置:
- 在方法中,this 指的是所有者對象。
- 單獨的情況下,this 指的是全局對象。
- 在函數中,this 指的是全局對象。
- 在函數中,嚴格模式下,this 是 undefined。
- 在事件中,this 指的是接收事件的元素。
像 call() 和 apply() 這樣的方法可以將 this 引用到任何對象。
5.閉包的理解和優缺點+
- 能夠讀取其他函數內部變量的函數/定義在一個函數內部的函數;
- 閉包的作用是可以創建封閉作用域
- 閉包的優點:可以避免全局變量的污染
- 閉包的缺點:常駐內存,會增大內存使用量,使用不當很容易造成內存泄露
6.防抖和節流的使用場景+
debounce (防抖)函數防抖在執行目標方法時,會等待一段時間。當又執行相同方法時,若前一個定時任務未執行完,則 clear 掉定時任務,重新定時。
- search搜索聯想,用戶在不斷輸入值時,用防抖來節約請求資源。
- window觸發resize的時候,不斷的調整瀏覽器窗口大小會不斷的觸發這個事件,用防抖來讓其只觸發一次
const _.debounce = (func, wait) => {
let timer;
return () => {
clearTimeout(timer);
timer = setTimeout(func, wait);
};
};
throttle (節流)是爲了限制函數一段時間內只能執行一次,在延時的時間內,方法若被觸發,則直接退出方法
- 鼠標不斷點擊觸發,mousedown(單位時間內只觸發一次)
- 監聽滾動事件,比如是否滑到底部自動加載更多,用throttle來判斷
const _.throttle = (func, wait) => {
let timer;
return () => {
if (timer) {
return;
}
timer = setTimeout(() => {
func();
timer = null;
}, wait);
};
};
7.瀏覽器的事件觸發+
冒泡和捕獲,事件流,捕獲 => 目標階段 => 冒泡
addEventListener(‘click’,function(){},false) 冒泡階段觸發
addEventListener(‘click’,function(){},true) 捕獲階段觸發
長列表場景:事件代理,將事件綁定到父元素,通過冒泡將其冒到父元素上進行處理,target屬性用來區分那個子元素.優點,節省內存,不用爲新增元素綁定事件。
阻止冒泡:stopPropagation()
8.== 和 === 的區別+
==, 兩邊值類型不同的時候,要先進行類型轉換,再比較。
===,不做類型轉換,類型不同的一定不等。
9.數組去重排序+
數組去重:
function unique (arr) {
return Array.from(new Set(arr))
}
數組排序:function cmp(a,b){return a-b}; array.sort(cmp);
10.淺拷貝與深拷貝++
淺拷貝: =號符/Array.prototype.slice() — 數組/Object.assign() — 對象
深拷貝:JSON.parse(JSON.stringify());
//遞歸實現
function isObj(obj) {
return (typeof obj === 'object' || typeof obj === 'function') && obj !== null
}
function deepCopy(obj) {
let tempObj = Array.isArray(obj) ? [] : {}
for(let key in obj) {
tempObj[key] = isObj(obj[key]) ? deepCopy(obj[key]) : obj[key]
}
return tempObj
}
11.判斷一個對象是不是promise+
function isPromise(e){
return !!e&&typeof e.then=="function"
}
12.事件隊列+
- 整體
script
作爲第一個宏任務進入主線程。 - 遇到
setTimeout
,其回調函數被分發到宏任務Event Queue中。 - 遇到
Promise
,new Promise直接執行,輸出Promise。then被分發到微任務Event Queue中。 - 遇到console.log,立即執行,輸出。
- 整體代碼
script
作爲第一個宏任務執行結束,看看有哪些微任務?我們發現了then
在微任務Event Queue裏面,執行。 - ok,第一輪事件循環結束了,我們開始第二輪循環,當然要從宏任務Event Queue開始。我們發現了宏任務Event Queue中
setTimeout
對應的回調函數,立即執行。 - 所有代碼結束。
13.內置類型
- null
- undefind
- 布爾值
- 數字
- 字符串
- 對象
- symbol
14.原型鏈
當訪問對象中的屬性或方法時,如果對象中沒有該屬性或方法,則會向此對象的 proto 尋找該屬性或方法,如果找了,就返回該屬性,若沒有找到,則繼續向此對象的 proto .proto 查找該屬性,一直訪問的windows對象,都沒有返回undefind
- 在任何對象上查找某個屬性時,會先在其自身上找,當查找不到時,會在此對象的 proto 屬性上去查找
- 可以用 Object.create§ 創建一個 proto 爲 p 的對象,即返回的對象的 proto 指向 p
- 可以通過 Object.getPrototypeOf(obj) 獲得 obj 對象的【proto】
- 其與對象的 proto 屬性其實是同一個東西,只是後者更加標準
- 但在更早的瀏覽器中,這兩者都是不可用的
- 可以通過Object.setPrototypeOf(obj1, obj2)設置obj1對象的__proto__爲obj2
15.JS裏有那些異步處理的方法
- 回調函數
- 事件監聽
- 發佈/訂閱
- Promises對象
16.瀏覽器新增的異步請求方式?跨域參數
fetch 調用時不會帶cookie
mode: ‘cors’,
17.模塊化規範
Commonjs、amd、cmd
18.es6擴展運算符使用場景
- 數據連接、合併
- 替換apply方法,一般在函數調用時處理參數
- 數組對象的拷貝
- 字符串轉數組
19.箭頭函數的特點和使用場景
特點:
-
箭頭函數會捕獲其所在父執行上下文的
this
值,作爲自己的this
值; -
箭頭函數不能作爲構造函數,和 new 一起用就會拋出錯誤;
-
箭頭函數沒有原型屬性
使用場景:在任何需要綁定
this
到父執行上下文,而不是函數本身時,箭頭函數十分適用。
20.import/export和require有什麼區別?
是語法層級的
方便靜態分析和優化
21.如何判斷一個變量是不是數組
現在: Array.isArray()
以前: Object.toString.call(val) == ‘[object Array]’
22.類數組對象怎麼轉換爲數組
Array.from(arrayLike)
Array.prototype.slice.call(arrayLike)
23.for…in 和 Object.keys的區別
for…in 會遍歷所有可枚舉屬性
Object.keys 返回自有可枚舉屬性組成的數組
24.純函數的特點及其好處
特點:相同輸入,永遠得到相同輸出
好處:沒有副作用,可測試性
ES6相關
1.let/const ++
let不會提升
const設置的原始值是不可以改變,但設置的對象內的屬性值是可以改變的
2.async/await ++
是生成器函數的語法糖 es7出現的 返回promise
3.promise++
有3個狀態,進行中,已完成,已失敗 / 特點:一旦狀態改變就不會在變
4.``模版字符串,裏面可以寫變量+
5.介紹class和ES5的類以及區別 +
必須new
原型上的方法自動不可枚舉
繼承時必須調用super
6.for in 和 for of 區別 +
for of 循環的是數組/字符串的值,不能循環普通對象/遍歷 可迭代對象(iterable object) 定義的可迭代的數據 ,比如遍歷 Array,Map,Set,String,TypedArray,arguments 等對象的數據。
for in 循環的是數組/字符串/對象的下標或key 循環對象及其原型上的可枚舉屬性/以任意順序遍歷對象的可枚舉屬性 (enumerable properties),包括對象從其構造函數原型中繼承的屬性。
如何使對象可以使用for of
newObj[Symbol.iterator] = function* (){
let keys = Object.keys( this )
for(let i = 0, l = keys.length; i < l; i++){
yield this[keys[i]]
}
}
7.ES6關於數組的一些處理 +++
- map對數組各個元素調用指定函數,並返回新數組
- filter過濾出滿足條件的元素
- reduce將數組中所有的元素迭代出一個值
- find查找一個符合條件的元素
- slice() 返回數組的一部分
- splice() 插入、刪除或替換數組元素
pop/push/shift/unshift會改變原數組
8.ES6關於對象的一些處理+
- object.assign()
9.劫持,代理proxy
10.裝飾器
@符號