做爲一個前端菜鳥的我,面試經驗和工做經驗並不豐富,但大大小小也面試過很多互聯網聖地,今天就講講筆者今年初面試鵝廠的經驗,但願對你們有所幫助!後面的答案爲自行整理,若有疏漏,歡迎指正!javascript
第二篇地址html
適用範圍: 一到兩年的菜鳥前端開發工程師前端
筆者狀況: 筆者一共面試了好幾輪技術面,最終結果技術面經過。java
筆者感言: 多是鵝廠大佬感受個人經驗不豐富的緣由,感受面試的大部分問題都是以基礎爲主。我的感受大廠仍是很是重視基礎的,特別是對工做經驗尚淺或者是校招生而言。因此react
重視基礎和原理es6
重視基礎和原理web
重視基礎和原理面試
如下,筆者會結合面試官問的問題一一道來...跨域
騰訊面試官(小騰):你好,我是騰訊面試官,巴拉巴拉......先自我介紹一下(聲音特別溫柔😝)!數組
筆者:我...
小騰:那咱們就簡單的聊一下一些基礎的前端知識!
。。。。。。
這通面試電話,面試官主要問了我4個前端相關問題。
1.知道什麼是事件委託嗎?
2.對Promise瞭解嗎?
3.window的onload事件和domcontentloaded誰先誰後?
4.你以前遇到過跨域問題嗎?是怎麼解決的。
衆人皆知,不以結婚爲目的的戀愛都是耍流氓,額,不,跑題了😁。。。不給答案的面試題都是來騙點擊量的😝!!!因爲這些問題實在過於簡單,可是涉及面又挺廣的,還請你們自行百度(千萬不要由於這個不給我贊,你的贊是寶寶持續分享的動力QAQ)。
啊呀,羅裏吧嗦的,老太婆的裹腳布...,我寫到這裏,被主管劈頭蓋臉就是一頓!如今的年輕人時間寶貴,喜歡乾貨,不喜歡你這磨磨唧唧的!如此,只能乾貨先行了(你們若是喜歡個人行文風格,就點個贊,或者評論一下唄,筆者特別想懟一下那個主管)!
乾貨以下,答案爲本身整理,若是有誤,歡迎指出!
一.有一個類以下:
function Person(name) { this.name = name } let p = new Person('Tom');
1. p.__proto__
等於什麼?
答案: Person.prototype
2. Person.__proto__
等於什麼?
答案: Function.prototype
解析:
1,2兩問其實問的是同一個問題,都是考察原型鏈相關的知識,咱們只須要記住一句話就能夠迎刃而解。實例的__proto__屬性(原型)等於其構造函數的prototype屬性。實例p的構造函數爲Person,而Person的構造函數爲Function,結果就一目瞭然了。
舉一反三
var foo = {}, F = function(){}; Object.prototype.a = 'value a'; Function.prototype.b = 'value b'; console.log(foo.a) console.log(foo.b) console.log(F.a) console.log(F.b)
這裏就不給答案了,你們本身分析一下,而後再去控制檯運行一下吧!冬天到了,動動手,暖一暖,有木有以爲筆者仍是至關的貼心的!!!
3. 若將題幹改成
function Person(name) { this.name = name return name; } let p = new Person('Tom');
實例化Person過程當中,Person返回什麼(或者p等於什麼)?
答案:
{name: 'Tom'}
4. 若將題幹改成
function Person(name) { this.name = name return {} } let p = new Person('Tom');
實例化Person過程當中,Person返回什麼(或者p等於什麼)?
答案:
{}
解析
構造函數不須要顯示的返回值。使用new來建立對象(調用構造函數)時,若是return的是非對象(數字、字符串、布爾類型等)會忽而略返回值;若是return的是對象,則返回該對象(注:若return null也會忽略返回值)。
5. typeof和instanceof的區別
答案:
在 JavaScript 中,判斷一個變量的類型嚐嚐會用 typeof 運算符,在使用 typeof 運算符時採用引用類型存儲值會出現一個問題,不管引用的是什麼類型的對象,它都返回 「object」。
instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。 語法:object instanceof constructor 參數:object(要檢測的對象.)constructor(某個構造函數) 描述:instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上。
答案是我整理後的,可能以爲我回答的並不許確,面試官又舉了一個例子給我。
6. 若是Student inherit from Person(Student類繼承Person,需是基於原型的繼承),let s = new Student('Lily'),那麼s instanceof Person返回什麼?
function Person (name) { this.name = name; } function Student () { } Student.prototype = Person.prototype; Student.prototype.constructor = Student; let s = new Student('Tom'); console.log(s instanceof Person); // 返回 true
答案: true
7. new和instanceof的內部機制
答案
- 建立一個新對象,同時繼承對象類的原型,即Person.prototype;
- 執行對象類的構造函數,同時該實例的屬性和方法被this所引用,即this指向新構造的實例;
- 若是構造函數return了一個新的「對象」,那麼這個對象就會取代整個new出來的結果。若是構造函數沒有return對象,那麼就會返回步驟1所建立的對象,即隱式返回this。(通常狀況下構造函數不會返回任何值,不過在一些特殊狀況下,若是用戶想覆蓋這個值,能夠選擇返回一個普通的對象來覆蓋。)
用代碼來闡述
// let p = new Person() let p = (function () { let obj = {}; obj.__proto__ = Person.prototype; // 其餘賦值語句... return obj; })();
下面經過代碼闡述instanceof的內部機制,假設如今有 x instanceof y 一條語句,則其內部實際作了以下判斷:
while(x.__proto__!==null) { if(x.__proto__===y.prototype) { return true; } x.__proto__ = x.__proto__.proto__; } if(x.__proto__==null) {return false;}
x會一直沿着隱式原型鏈__proto__向上查找直到x.__proto__.__proto__......===y.prototype
爲止,若是找到則返回true,也就是x爲y的一個實例。不然返回false,x不是y的實例。
舉一反三
function F() {} function O() {} O.prototype = new F(); var obj = new O(); console.log(obj instanceof O); // true console.log(obj instanceof F); // true console.log(obj.__proto__ === O.prototype); // true console.log(obj.__proto__.__proto__ === F.prototype); // true
根據new 的內部機制改寫上面代碼
function F() {} function O() {} var obj = (function () { var obj1 = {}; obj1.__proto__ = F.prototype; // new F(); O.prototype = obj1; // O.prototype = new F(); obj.__proto__ = O.prototype; // new O(); obj.__proto__ = obj1; return obj; })();
結合instanceof內部機制很容易得出正確答案。
若是稍微調整一下代碼順序,結果將迥然不一樣
function F() {} function O() {} var obj = new O(); O.prototype = new F(); console.log(obj instanceof O); // false console.log(obj instanceof F); // false console.log(obj.__proto__ === O.prototype); // false console.log(obj.__proto__.__proto__ === F.prototype); // false
具體緣由,請讀者自行分析,若是仍是有疑問,能夠在評論區提出!
其實上面不少問題都是考察原型鏈相關的知識,這裏給出一張必須理解的原型鏈圖,原諒我盜了一張圖。
問到這裏個人腦殼已經有點漿糊了,原諒我太菜了!!
8.下面代碼輸出什麼?
for(var i = 0; i < 10; i++) { setTimeout(() => { console.log(i) }, 0) }
答案: 10個10
若要輸出從0到9,怎麼辦?
答案: 將var改成let,或者使用閉包。
// 使用閉包 for(var i = 0; i < 10; i++) { (function (i) { setTimeout(() => { console.log(i) }, 0); })(i); }
9. 剛剛咱們用到了箭頭函數,說一下箭頭函數This指向問題?
答案: 默認指向在定義它時,它所處的對象,而不是執行時的對象,定義它的時候,可能環境是window(即繼承父級的this)。
若是對This還有不清楚的地方,能夠參考個人另外一篇文章完全理解JavaScript中的this。
10. for...in迭代和for...of有什麼區別?
11.說一下你對generator的瞭解?
答案: 建議你們查看阮一峯老師的generator相關章節
12.使用過flex佈局嗎?flex-grow和flex-shrink屬性有什麼用?
答案: flex-grow:項目的放大比例,默認爲0,即若是存在剩餘空間,也不放大。flex-shrink:項目的縮小比例,默認爲1,即若是空間不足,該項目將縮小。
想完全理解flex,能夠查看阮一峯老師的Flex佈局教程:語法篇
13. 說一下macrotask 和 microtask?並說出下面代碼的運行結果。
console.log('a'); setTimeout(() => { console.log('b'); }, 0); console.log('c'); Promise.resolve().then(() => { console.log('d'); }) .then(() => { console.log('e'); }); console.log('f');
答案: 輸出結果爲 acfdeb,而關於macrotask和microtask能夠繼續留意筆者後篇文章,亦可自行搜索。不過能夠看一下盜的一張圖。
14. Http請求中的keep-alive有了解嗎。
答案:
在http早期,每一個http請求都要求打開一個tpc socket鏈接,而且使用一次以後就斷開這個tcp鏈接。 使用keep-alive能夠改善這種狀態,即在一次TCP鏈接中能夠持續發送多份數據而不會斷開鏈接。經過使用keep-alive機制,能夠減小tcp鏈接創建次數,也意味着能夠減小TIME_WAIT狀態鏈接,以此提升性能和提升httpd服務器的吞吐率(更少的tcp鏈接意味着更少的系統內核調用,socket的accept()和close()調用)。 可是,keep-alive並非免費的午飯,長時間的tcp鏈接容易致使系統資源無效佔用。配置不當的keep-alive,有時比重複利用鏈接帶來的損失還更大。因此,正確地設置keep-alive timeout時間很是重要。
15. React中的controlled component 和 uncontrolled component區別(受控組件和不受控組件)。
16. 瞭解過react-router內部實現機制嗎?
**答案:**請看這篇文章react-router的實現原理
17.數組扁平化處理:實現一個flatten方法,使得輸入一個數組,該數組裏面的元素也能夠是數組,該方法會輸出一個扁平化的數組。
// Example let givenArr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10]; let outputArr = [1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10] // 實現flatten方法使得 flatten(givenArr)——>outputArr
年輕的我是用遞歸實現的QAQ,個人答案
function flatten(arr){ var res = []; for(var i=0;i<arr.length;i++){ if(Array.isArray(arr[i])){ res = res.concat(flatten(arr[i])); }else{ res.push(arr[i]); } } return res; }
其實你還能夠這樣
function flatten(arr){ return arr.reduce(function(prev,item){ return prev.concat(Array.isArray(item)?flatten(item):item); },[]); }
還可使用ES6拓展運算符
function flatten(arr){ while(arr.some(item=>Array.isArray(item)){ arr = [].concat(...arr); } return arr; }
18.若是在17問的前提下,要作去重和排序處理又該怎麼作(不用給出具體代碼)。
**答案:**最好封裝一個數組方法的類,該類包含flatten(扁平化)、sort(排序)和unique(去重)等方法。
二面就這樣過去了,懷着忐忑的心情等待結果中,文章有點長了,欲知後面的面試題,請聽下回分解!!!
做者:WaterMan連接:https://juejin.im/post/5c19c1b6e51d451d1e06c163來源:掘金著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。