2020-3月份前端面試總結——js/es6相關

JS方面

備註: + 代表被問到的次數,沒有 + 代表自己整理了,但沒被問到

1.js繼承的方式+

  1. 原型鏈繼承
  2. 借用構造函數繼承(通過call()實現)
  3. 組合繼承(原型+借用構造)
  4. 通過ES6中class的extends關鍵字實現繼承

2.NEW操作符做了那些事情+

  1. 創建一個新對象;
  2. 將構造函數的作用域賦給新對象(因此this就指向了這個新對象);
  3. 執行構造函數中的代碼(爲這個新對象添加屬性);
  4. 返回新對象

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.裝飾器

​ @符號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章