【轉(zhuǎn)載】高級前端面試題目大全(一)

高級前端面試題目大全(一)

原文鏈接:http://www.reibang.com/p/7c6e4d21bf77

第 1 題:(滴滴、餓了么)寫 React / Vue 項目時為什么要在列表組件中寫 key帖蔓,其作用是什么叠骑?

1. 更準確
因為帶key就不是就地復(fù)用了,在isSameNode()函數(shù) a.key === b.key對比中可以避免就地復(fù)用的情況。所以會更加準確绍哎。

2. 更快
利用key的唯一性生成map對象來獲取對應(yīng)節(jié)點,比遍歷方式更快。主要是為了提升diff【同級比較】的效率携龟。自己想一下自己要實現(xiàn)前后列表的diff,如果對列表的每一項增加一個key勘高,即唯一索引峡蟋,那就可以很清楚的知道兩個列表誰少了誰沒變。而如果不加key的話华望,就只能一個個對比了蕊蝗。
vue和react都是采用diff算法來對比新舊虛擬節(jié)點,從而更新節(jié)點赖舟。在vue的diff函數(shù)中(建議先了解一下diff算法過程)蓬戚。 在交叉對比中,當新節(jié)點跟舊節(jié)點頭尾交叉對比沒有結(jié)果時宾抓,會根據(jù)新節(jié)點的key去對比舊節(jié)點數(shù)組中的key子漩,從而找到相應(yīng)舊節(jié)點(這里對應(yīng)的是一個key => index 的map映射)。如果沒找到就認為是一個新增節(jié)點石洗。而如果沒有key幢泼,那么就會采用遍歷查找的方式去找到對應(yīng)的舊節(jié)點。一種一個map映射讲衫,另一種是遍歷查找缕棵。相比而言。map映射的速度更快涉兽。 vue部分源碼如下:

解析:第 1 題

第 2 題:['1', '2', '3'].map(parseInt) what & why ?

首先讓我們回顧一下招驴,map函數(shù)的第一個參數(shù)callback:
var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])
這個callback一共可以接收三個參數(shù),其中第一個參數(shù)代表當前被處理的元素花椭,而第二個參數(shù)代表該元素的索引忽匈。

而parseInt則是用來解析字符串的,使字符串成為指定基數(shù)的整數(shù)矿辽。
parseInt(string, radix)
接收兩個參數(shù)丹允,第一個表示被處理的值(字符串)萎馅,第二個表示為解析時的基數(shù)伟桅。

了解這兩個函數(shù)后,我們可以模擬一下運行情況

parseInt('1', 0) //radix為0時讳苦,且string參數(shù)不以“0x”和“0”開頭時宾娜,按照10為基數(shù)處理批狐。這個時候返回1
parseInt('2', 1) //基數(shù)為1(1進制)表示的數(shù)中,最大值小于2,所以無法解析嚣艇,返回NaN
parseInt('3', 2) //基數(shù)為2(2進制)表示的數(shù)中承冰,最大值小于3,所以無法解析食零,返回NaN
map函數(shù)返回的是一個數(shù)組困乒,所以最后結(jié)果為[1, NaN, NaN]

解析:第 2 題

第 3 題:(挖財)什么是防抖和節(jié)流?有什么區(qū)別贰谣?如何實現(xiàn)娜搂?

JavaScript專題之跟著underscore學(xué)防抖
JavaScript專題之跟著 underscore 學(xué)節(jié)流

防抖
觸發(fā)高頻事件后n秒內(nèi)函數(shù)只會執(zhí)行一次,如果n秒內(nèi)高頻事件再次被觸發(fā)吱抚,則重新計算時間

思路
每次觸發(fā)事件時都取消之前的延時調(diào)用方法

    /* 防抖 */
    function dou(fn, wait) {
        var time = null;
        return function () {
            clearTimeout(time)
            // time = setTimeout(function () {
            //  console.log(this)//window 
            //  fn.apply(this, arguments)//這樣的話 this為window和直接 fn()調(diào)用是一樣的效果百宇,因為他們的this都是window
            // }, wait);
            time = setTimeout(() => {
                // console.log(this)//div
                fn.apply(this, arguments)//確保dou函數(shù)的this(上下文還是div)
            }, wait);
        }
    }
    function demo() {
        console.log('防抖啦')
    }
    // 用句柄事件綁定調(diào)用dou事件,所以this為div節(jié)點對象
    document.querySelector('div').addEventListener('scroll', dou(demo, 1000))

節(jié)流
高頻事件觸發(fā)秘豹,但在n秒內(nèi)只會執(zhí)行一次携御,所以節(jié)流會稀釋函數(shù)的執(zhí)行頻率

思路
每次觸發(fā)事件時都判斷當前是否有等待執(zhí)行的延時函數(shù)

    /* 節(jié)流 */
    function throttle(func, wait) {
        var previous = 0;
        return function () {
            var now = +new Date();
            if (now - previous > wait) {
                func.apply(this, arguments);
                previous = now;
            }
        }
    }
    function getUserAction() {
        console.log(`每秒1秒內(nèi)打印一次`)
    }
    document.querySelector('div').addEventListener('click', throttle(getUserAction, 1000))

解析:第 3 題

第 4 題:介紹下 Set、Map憋肖、WeakSet 和 WeakMap 的區(qū)別因痛?

Set
成員唯一、無序且不重復(fù)
[value, value]岸更,鍵值與鍵名是一致的(或者說只有鍵值,沒有鍵名)
可以遍歷膊升,方法有:add怎炊、delete、has

WeakSet
成員都是對象
成員都是弱引用廓译,可以被垃圾回收機制回收评肆,可以用來保存DOM節(jié)點,不容易造成內(nèi)存泄漏
不能遍歷非区,方法有add瓜挽、delete、has

Map
本質(zhì)上是鍵值對的集合征绸,類似集合
可以遍歷久橙,方法很多可以跟各種數(shù)據(jù)格式轉(zhuǎn)換

WeakMap
只接受對象作為鍵名(null除外),不接受其他類型的值作為鍵名
鍵名是弱引用管怠,鍵值可以是任意的淆衷,鍵名所指向的對象可以被垃圾回收,此時鍵名是無效的
不能遍歷渤弛,方法有g(shù)et祝拯、set、has她肯、delete

解析:第 4 題

第 5 題:介紹下深度優(yōu)先遍歷和廣度優(yōu)先遍歷佳头,如何實現(xiàn)鹰贵?

解析:第 5 題

第 6 題:請分別用深度優(yōu)先思想和廣度優(yōu)先思想實現(xiàn)一個拷貝函數(shù)?

解析:第 6 題

第 7 題:ES5/ES6 的繼承除了寫法以外還有什么區(qū)別康嘉?

先看ES5的繼承(原型鏈繼承)

function a() {
  this.name = 'a';
}
a.prototype.getName = function getName() {
  return this.name
}
function b() {}
b.prototype = new a();
console.log(b.prototype.__proto__ === a.prototype); // true
console.log(b.__proto__ === a); // false
console.log(b.__proto__); // [Function]

ES6繼承

class A {
  constructor(a) {
    this.name = a;
  }
  getName() {
    return this.name;
  }
}

class B extends A{
  constructor() {
    super();
  }
}

console.log(B.prototype.__proto__ === A.prototype); // true
console.log(B.__proto__ === A); // true
console.log(B.__proto__); // [Function: A]

對比代碼可以知道碉输,子類的繼承都是成功的,但是問題出在凄鼻,子類的 __proto__ 指向不一樣腊瑟。

ES5 的子類和父類一樣,都是先創(chuàng)建好块蚌,再實現(xiàn)繼承的闰非,所以它們的指向都是 [Function]

ES6 則得到不一樣的結(jié)果峭范,它指向父類财松,那么我們應(yīng)該能推算出來,它的子類是通過 super 來改造的纱控。

根據(jù) es6--阮一峰 在class繼承里面的說法辆毡,是這樣子的:

引用阮一峰的 ECMAScript6入門 的class繼承篇

子類必須在constructor方法中調(diào)用super方法,否則新建實例時會報錯甜害。這是因為子類自己的this對象舶掖,必須先通過父類的構(gòu)造函數(shù)完成塑造,得到與父類同樣的實例屬性和方法尔店,然后再對其進行加工眨攘,加上子類自己的實例屬性和方法。如果不調(diào)用super方法嚣州,子類就得不到this對象鲫售。

ES5 的繼承,實質(zhì)是先創(chuàng)造子類的實例對象this该肴,然后再將父類的方法添加到this上面(Parent.apply(this))情竹。ES6 的繼承機制完全不同,實質(zhì)是先將父類實例對象的屬性和方法匀哄,加到this上面(所以必須先調(diào)用super方法)秦效,然后再用子類的構(gòu)造函數(shù)修改this

1拱雏、class 聲明會提升棉安,但不會初始化賦值。Foo 進入暫時性死區(qū)铸抑,類似于 let贡耽、const 聲明變量。

2、class 聲明內(nèi)部會啟用嚴格模式蒲赂。

3阱冶、class 的所有方法(包括靜態(tài)方法和實例方法)都是不可枚舉的。

4滥嘴、class 的所有方法(包括靜態(tài)方法和實例方法)都沒有原型對象 prototype木蹬,所以也沒有[[construct]],不能使用 new 來調(diào)用若皱。

5镊叁、必須使用 new 調(diào)用 class。

6走触、class 內(nèi)部無法重寫類名

解析:第 7 題

第 8 題:setTimeout晦譬、Promise、Async/Await 的區(qū)別

其中settimeout的回調(diào)函數(shù)放到宏任務(wù)隊列里互广,等到執(zhí)行棧清空以后執(zhí)行敛腌; promise.then里的回調(diào)函數(shù)會放到相應(yīng)宏任務(wù)的微任務(wù)隊列里,等宏任務(wù)里面的同步代碼執(zhí)行完再執(zhí)行惫皱;async函數(shù)表示函數(shù)里面可能會有異步方法像樊,await后面跟一個表達式,async方法執(zhí)行時旅敷,遇到await會立即執(zhí)行表達式生棍,然后把表達式后面的代碼放到微任務(wù)隊列里,讓出執(zhí)行棧讓同步代碼先執(zhí)行媳谁。

解析:第 8 題

第 9 題:(頭條足绅、微醫(yī))Async/Await 如何通過同步的方式實現(xiàn)異步

async await 用于把異步請求變?yōu)橥秸埱蟮姆绞?第一個請求的返回值作為后面一個請求的參數(shù),其中每一個參數(shù)都是一個promise對象

例如:這種情況工作中會經(jīng)常遇到

(async () => {
    var a = await A();
    var b = await B(a);
    var c = await C(b);
    var d = await D(c);
})();

解析:第 9 題

第 10 題:(頭條)異步筆試題

請寫出下面代碼的運行結(jié)果

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}
console.log('script start');
setTimeout(function() {
    console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
    console.log('promise1');
    resolve();
}).then(function() {
    console.log('promise2');
});
console.log('script end');
復(fù)制代碼

解析:第 10 題

第 11 - 20 題

第 11 題:(攜程)算法手寫題

已知如下數(shù)組:

var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];

編寫一個程序?qū)?shù)組扁平化去并除其中重復(fù)部分數(shù)據(jù),最終得到一個升序且不重復(fù)的數(shù)組

    var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
    // 方法一
    console.log(Array.from(new Set(arr.flat(Infinity))).sort((a, b) => a - b))
    // 方法二
    console.log(Array.from(new Set(arr.toString().split(','))).map(Number).sort((a, b) => a - b))

    // 方法三
    // 第一步:扁平化
    let newArr = [];
    function flat(originArr) {
        if ({}.toString.call(originArr) === '[object Array]') {
            for (let i of originArr) {
                if ({}.toString.call(i) === '[object Array]') {
                    arguments.callee(i)
                } else {
                    newArr.push(i)
                }
            }
        }
        return newArr;
    }
    console.log(flat(arr))
    // 第二步:去重
    var newArr1 = [];
    for (let i of newArr) {
        if (!newArr1.includes(i)) newArr1.push(i);
    }
    // 第三步:排序 可以采用相關(guān)算法處理
    console.log(newArr1.sort((a, b) => a - b))

解析:第 11 題

第 12 題:(滴滴韩脑、挖財、微醫(yī)粹污、憾味啵康)JS 異步解決方案的發(fā)展歷程以及優(yōu)缺點。

1. 回調(diào)函數(shù)(callback)

    setTimeout(() => {
        // callback 函數(shù)體
    }, 1000)

缺點:回調(diào)地獄壮吩,不能用 try catch 捕獲錯誤进苍,不能 return`
回調(diào)地獄的根本問題在于

缺乏順序性: 回調(diào)地獄導(dǎo)致的調(diào)試困難,和大腦的思維方式不符
嵌套函數(shù)存在耦合性鸭叙,一旦有所改動觉啊,就會牽一發(fā)而動全身,即(控制反轉(zhuǎn),嵌套函數(shù)過多的多話沈贝,很難處理錯誤

    ajax('XXX1', () => {
        // callback 函數(shù)體
        ajax('XXX2', () => {
            // callback 函數(shù)體
            ajax('XXX3', () => {
                // callback 函數(shù)體
            })
        })
    })

優(yōu)點:解決了同步的問題(只要有一個任務(wù)耗時很長杠人,后面的任務(wù)都必須排隊等著,會拖延整個程序的執(zhí)行。)

2. Promise
Promise就是為了解決callback的問題而產(chǎn)生的嗡善。

Promise 實現(xiàn)了鏈式調(diào)用辑莫,也就是說每次 then 后返回的都是一個全新 Promise,如果我們在 then 中 return 罩引,return 的結(jié)果會被Promise.resolve() 包裝

優(yōu)點:解決了回調(diào)地獄的問題

    ajax('XXX1')
        .then(res => {
            // 操作邏輯
            return ajax('XXX2')
        }).then(res => {
            // 操作邏輯
            return ajax('XXX3')
        }).then(res => {
            // 操作邏輯
        })

缺點:無法取消 Promise 各吨,錯誤需要通過回調(diào)函數(shù)來捕獲

3. Generator
特點:可以控制函數(shù)的執(zhí)行,可以配合 co 函數(shù)庫使用

    function* fetch() {
        yield ajax('XXX1', () => { })
        yield ajax('XXX2', () => { })
        yield ajax('XXX3', () => { })
    }
    let it = fetch()
    let result1 = it.next()
    let result2 = it.next()
    let result3 = it.next()

4. Async / await
async袁铐、await 是異步的終極解決方案

優(yōu)點是:代碼清晰揭蜒,不用像 Promise 寫一大堆 then 鏈,處理了回調(diào)地獄的問題

缺點:await 將異步代碼改造成同步代碼剔桨,如果多個異步操作沒有依賴性而使用 await 會導(dǎo)致性能上的降低屉更。

async function test() {
        // 以下代碼沒有依賴性的話,完全可以使用 Promise.all 的方式
        // 如果有依賴性的話领炫,其實就是解決回調(diào)地獄的例子了
        await fetch('XXX1')
        await fetch('XXX2')
        await fetch('XXX3')
    }

解析:第 12 題

第 13 題:(微醫(yī))Promise 構(gòu)造函數(shù)是同步執(zhí)行還是異步執(zhí)行偶垮,那么 then 方法呢?

    const promise = new Promise((resolve, reject) => {
        console.log(1)
        resolve()
        console.log(2)
    })

    promise.then(() => {
        console.log(3)
    })

    console.log(4)

執(zhí)行結(jié)果是:1243
promise構(gòu)造函數(shù)是同步執(zhí)行的帝洪,then方法是異步執(zhí)行的

解析:第 13 題

第 14 題:(兌吧)情人節(jié)福利題似舵,如何實現(xiàn)一個 new

先理清楚 new 關(guān)鍵字調(diào)用函數(shù)都的具體過程,那么寫出來就很清楚了

首先創(chuàng)建一個空的對象葱峡,空對象的 ___proto____屬性指向構(gòu)造函數(shù)的原型對象
把上面創(chuàng)建的空對象賦值構(gòu)造函數(shù)內(nèi)部的this砚哗,用構(gòu)造函數(shù)內(nèi)部的方法修改空對象
如果構(gòu)造函數(shù)返回一個非基本類型的值,則返回這個值砰奕,否則上面創(chuàng)建的對象

function _new(fn, ...arg) {
    var obj = Object.create(fn.prototype);
    const result = fn.apply(obj, ...arg);
    return Object.prototype.toString.call(result) == '[object Object]' ? result : obj;
}

解析:第 14 題

第 15 題:(網(wǎng)易)簡單講解一下http2的多路復(fù)用

解析:第 15 題

第 16 題:談?wù)勀銓CP三次握手和四次揮手的理解

解析:第 16 題

第 17 題:A蛛芥、B 機器正常連接后,B 機器突然重啟军援,問 A 此時處于 TCP 什么狀態(tài)

如果A 與 B 建立了正常連接后仅淑,從未相互發(fā)過數(shù)據(jù),這個時候 B 突然機器重啟胸哥,問 A 此時處于 TCP 什么狀態(tài)涯竟?如何消除服務(wù)器程序中的這個狀態(tài)?(超綱題空厌,了解即可)

解析:第 17 題

第 18 題:(微醫(yī))React 中 setState 什么時候是同步的庐船,什么時候是異步的?

解析:第 18 題

第 19 題:React setState 筆試題嘲更,下面的代碼輸出什么筐钟?

class Example extends React.Component {
  constructor() {
    super();
    this.state = {
      val: 0
    };
  }

  componentDidMount() {
    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 1 次 log

    this.setState({val: this.state.val + 1});
    console.log(this.state.val);    // 第 2 次 log

    setTimeout(() => {
      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 3 次 log

      this.setState({val: this.state.val + 1});
      console.log(this.state.val);  // 第 4 次 log
    }, 0);
  }

  render() {
    return null;
  }
};
復(fù)制代碼

解析:第 19 題

第 20 題:介紹下 npm 模塊安裝機制,為什么輸入 npm install 就可以自動安裝對應(yīng)的模塊赋朦?

解析:第 20 題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篓冲,一起剝皮案震驚了整個濱河市李破,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纹因,老刑警劉巖喷屋,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞭恰,居然都是意外死亡屯曹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門惊畏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恶耽,“玉大人,你說我怎么就攤上這事颜启⊥导螅” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵缰盏,是天一觀的道長涌萤。 經(jīng)常有香客問我,道長口猜,這世上最難降的妖魔是什么负溪? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮济炎,結(jié)果婚禮上川抡,老公的妹妹穿的比我還像新娘。我一直安慰自己须尚,他們只是感情好崖堤,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耐床,像睡著了一般密幔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撩轰,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天老玛,我揣著相機與錄音,去河邊找鬼钧敞。 笑死,一個胖子當著我的面吹牛麸粮,可吹牛的內(nèi)容都是我干的溉苛。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼弄诲,長吁一口氣:“原來是場噩夢啊……” “哼愚战!你這毒婦竟也來了娇唯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤寂玲,失蹤者是張志新(化名)和其女友劉穎塔插,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拓哟,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡想许,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了断序。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片流纹。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖违诗,靈堂內(nèi)的尸體忽然破棺而出漱凝,到底是詐尸還是另有隱情,我是刑警寧澤诸迟,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布茸炒,位于F島的核電站,受9級特大地震影響阵苇,放射性物質(zhì)發(fā)生泄漏壁公。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一慎玖、第九天 我趴在偏房一處隱蔽的房頂上張望贮尖。 院中可真熱鬧,春花似錦趁怔、人聲如沸湿硝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽关斜。三九已至,卻和暖如春铺浇,著一層夾襖步出監(jiān)牢的瞬間痢畜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工鳍侣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丁稀,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓倚聚,卻偏偏與公主長得像线衫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惑折,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 以下題目是根據(jù)網(wǎng)上多份面經(jīng)收集而來的授账,題目相同意味著被問的頻率比較高枯跑,有問題歡迎留言討論,喜歡可以點贊關(guān)注白热。 1....
    Aniugel閱讀 8,814評論 2 6
  • 第 41 - 50 題 第 41 題:下面代碼輸出什么 解析:第 41題[https://github.com/A...
    Aniugel閱讀 3,231評論 0 7
  • 記錄和匯總看到的和碰到的前端面試題主要來源: https://github.com/Advanced-Fronte...
    Piscoo閱讀 226評論 0 0
  • 以下題目是根據(jù)網(wǎng)上多份面經(jīng)收集而來的敛助,題目相同意味著被問的頻率比較高,有問題歡迎留言討論屋确,喜歡可以點贊關(guān)注纳击。 1、...
    lessonSam閱讀 295評論 0 0
  • 近日乍恐,GitHub 上一位名為木易楊(yygmind)的開發(fā)者评疗,在 GitHub 中建了一個名為 Advanced...
    grain先森閱讀 989評論 0 44