直通互聯網大廠前端面試系列(二)——JS / ES6+

傳送門

寫在前面

JavaScript = ECMAScript + DOM(文檔對象類型) + BOM(瀏覽器對象類型)。我們的重頭戲來了,因爲JS的內容實在太多了,所以我把算法、框架、網絡部分的內容都放到了後面的分類裏,這樣也有利於我們的聚焦。
ES的變化可謂相當之快,2015年後每年一個版本(BOM和DOM相對變化不大)。多虧了babel,我們可以很愉快的使用ES的最新特性,而不用考慮兼容性的問題,相應的,我們每年都要學習一些新的語法。既然選擇了前端,那持續學習是跑不了的了,同學們做好心理準備,心裏默唸,我們是最pang棒的!

長期如何學習

如果你之前有過編碼經驗,那麼你一定知道我下面說的有多重要

  • 深入底層原理,JS也是一門編程語言,只要是編程語言其本質一定是相通的,這一點無論學習任何一種語言都是必然的。雖然是老生常談,但是真理往往都是經得住歲月考驗的。你理解的深度,決定了你以後的高度,出來混遲早要還的,缺的課早晚要補回來的。
  • 注意編碼規範,建議越早使用eslint越好,推薦最嚴格的airbnb的標準,它可以非常有效地規範你的代碼風格。良好的代碼風格能夠讓你少寫bug,快速修復bug,讓別人替你修完bug少罵幾句娘。就衝這幾點!夠不夠?!夠不夠?!
  • 多看經典的書,看書絕對是提升自己思維高度的最佳途徑。私以爲經過了一段時間的實戰,再去看書,纔是最有效果的。因爲這時候是帶着問題去看書的,每當看到與問題相呼應的地方,一定會有一種茅塞頓開的感覺,記憶尤其深刻。對於新手來說,多加練習反而纔是重要的,要在實戰中多積累問題,多思考,這也算是一種厚積薄發。不過呢,有些書即使是新手也是必須看的,“前端聖經”系列要是沒看過的話,實在是有點說不過去了。另外,針對老鳥,我推薦兩本讓我記憶深刻的書《鳥哥的linux私房菜》、《碼農翻身》。

短期如何突擊

短期能突擊的,就是幾個最容易考的難點,無論你是老鳥還是菜鳥,面試前最好都突擊一下,這些必考:

  • js數據類型及判斷
  • 閉包與作用域
  • this與執行上下文
  • 原型鏈與繼承(原型、構造函數、實例)
  • 異步任務
  • ES6+常用特性

別看知識點就這麼幾個,圍繞着它們出的題可謂變化無窮,想當年我隨便見到它們其中一個,都會腿發抖。那麼讓我們來看一下它們能變化到什麼程度

臨陣如何磨槍

JS的題一定是佔了面試絕大部分內容的,畢竟平時80%以上的開發時間都是用的它,最後強調一遍,下面的題,一定要保證每個知識點都弄明白了,這些題值得反覆地做。不怕做的慢,一定不要自欺欺人。哪怕一天能啃下來一道題,也是可以接受的。

請說出以下代碼打印的結果
if (1 == true) {console.log(1);};

if (1 === true ) {console.log(2);};

if ([]) {console.log(3);};

if ([] == []) {console.log(4);};

if ([] === []) {console.log(5);};

if (undefined == null) {console.log(6);};

if ('' == null) {console.log(7);};

if (NaN == NaN) {console.log(8);};

追問:

  • JS的數據類型有哪些?哪些是引用類型?它們有什麼特點?
  • 什麼是淺拷貝?什麼是深拷貝?請用JS實現一個深拷貝
  • 如何判斷數組類型?方法越多越好
  • typeof 和 instanceof 有什麼區別?
  • == 和 === 有什麼區別?==時發生了什麼?
  • 函數中的 arguments 是數組嗎?若不是,如何將它轉化爲真正的數組
  • 請說下Array的forEach、map、every、some、filter、reduce各有什麼功能
  • 如何遍歷一個對象?方法越多越好
以下代碼的結果是什麼?請解釋你的答案。
var fullname = 'John Doe';
var obj = {
  fullname: 'Colin Ihrig',
  prop: {
    fullname: 'Aurelio De Rosa',
    getFullname: function () {
      return this.fullname;
    }
  }
};
 
console.log(obj.prop.getFullname());
 
var test = obj.prop.getFullname;
 
console.log(test());
實現Function.prototype.bind方法, 使得以下程序最後能輸出’success’
function Animal(name, color) {
  this.name = name;
  this.color = color;
}
Animal.prototype.say = function () {
  return `I'm a ${this.color} ${this.name}`;
};
const Cat = Animal.bind(null, 'cat');
 
const cat = new Cat('white');
 
if (cat.say() === 'I\'m a white cat' && cat instanceof Cat && cat instanceof Animal) {
  console.log('success');
}

追問:

  • bind、call和apply有什麼區別?
  • 什麼是閉包?請實現一個“有緩存功能”的加法
  • 請用JS實現throttle(函數節流)函數。函數節流解釋: 對函數執行增加一個控制層,保證一段時間內(可配置)內只執行一次。此函數的作用是對函數執行進行頻率控制,常用於用戶頻繁觸發但可以以更低頻率響應的場景
  • debounce和throttle的區別?請用JS實現debounce
  • es6中的箭頭函數與普通函數有什麼區別?
請用至少2種方法,實現Cat繼承Animal的屬性,並比較各方法的優缺點
function Animal() {    
    this.species = "動物";  
}

function Cat(name, color) {    
    this.name = name;    
    this.color = color;  
}

追問:

  • 什麼是原型鏈?什麼是原型對象?
  • JS的最頂層對象是什麼?它的原型對象是什麼?
  • 什麼是構造函數?什麼是實例?
  • 如何通過一個實例訪問它的構造函數及原型對象?
  • new一個實例,經歷了什麼過程?
  • es6中的static的作用是什麼?用es5如何實現?
以最小的改動解決以下代碼的錯誤(可以使用es6)
const obj = {
  name: " jsCoder",
  skill: ["es6", "react", "angular"],
  say: function () {
    for (var i = 0, len = this.skill.length; i < len; i++) {
      setTimeout({
        console.log('No.' + i + this.name);
        console.log(this.skill[i]);
        console.log('--------------------------');
      }, 0);
      console.log(i);
    }
  }
};
obj.say();
 
/*
期望得到下面的結果:
1
2
3
No.1 jsCoder
es6
--------------------------
No.2 jsCoder
react
--------------------------
No.3 jsCoder
angular
--------------------------
*/

追問:

  • 如果不修改,會打印出什麼結果?
  • let、const、var有什麼區別?
  • 什麼是函數作用域?還有什麼其他作用域?如何工作的?
請說出以下代碼打印的結果
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');

追問:

  • JS單線程是怎麼運作的?請說下“異步”和“同步”的區別
  • 處理異步任務的方法有哪些?
  • 如何將一個普通異步函數封裝爲Promise?
  • 請實現一個同步的delay方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章