刷 攜程 地面業務 前端面試經歷

在簡書看到這篇面試題,結合做者的答案和我的的理解作了一下,因我的水平有限(不謙虛,確實很菜),若是我的作的有什麼不對的歡迎指出來,共同交流javascript

做者:詩和元芳 連接:www.jianshu.com/p/e6efcd993… 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。前端

筆試

題目一

<div id="d">
    <div id = "a"></div>
    <div id = "b"></div>
    <div id = "c"></div>
</div>
<script>
    var a = [document.getElementById('a'),document.getElementById('b'),document.getElementById('c')];
    var b = [document.getElementById('d').getElementsByTagName('div')];
</script>
複製代碼

問a 和 b 的區別java

咱們把結果打印出來看一下:react

a es6

b web

看MDN官方對Element.getElementsByTagName()這個說法的解釋: 「Element.getElementsByTagName()方法返回一個動態的包含全部指定標籤名的元素的HTML集合HTMLCollection。指定的元素的子樹會被搜索,不包括元素本身。返回的列表是動態的,這意味着它會隨着DOM樹的變化自動更新自身。因此,使用相同元素和相同參數時,沒有必要屢次的調用Element.getElementsByTagName() .」面試

不少人(包括我和做者)都會覺得這題差異是在b返回的是二維數組,其實都是想固然了。 a返回的是一個包含三個dom元素的數組,而b返回的是隻有一個HTMLCollection元素的數組。這是徹底的兩種結構且HTMLCollection並不繼承自Array.ajax

  • 一、HTMLCollection是及時更新的,當文檔中的DOM變化時,它是會隨之變化的
  • 二、HTMLCollection能夠用 HTMLCollection.item()HTMLCollection.namedItem() 這種方式來獲取內部元素。

題目二 數組去重

請手打一個數組去重的方法,題目是[1,2,3,2].distinct() = [1,2,3]。
複製代碼

關於數組去重的方法有不少,網上資料太多再也不贅述,做者用的是一種hash去重的方法。數據庫

Array.prototype.distinct = Array.prototype.distinct || function(){
            var len = this.length,
                  i = 0,
                  hash = {},
                  myArr = [];
        for(; i < len; i ++){
                  if(!hash[this[i]]){
                      hash[this[i]] = true;
                      myArr.push(this[i])
                  }
        }
    return myArr;
}
複製代碼

這種方法能夠達到題目中的要求,但並非一種嚴謹的數組去重方式。 假設咱們的的數組變成[1,2,3,2,'1'],這種方法就沒法達到去重的效果了,這種方式沒法區分數字1和字符串'1',還須要經過類型判斷。 關於數組去重,最簡單的是ES6的:編程

Array.prototype.distinct = Array.prototype.distinct||function(){
	console.log(this);
    return Array.from(new Set(this)); //return [...(new Set(this))];
}
複製代碼

題目三,考察閉包

function mo(){
    var x = 0;
    return function(){
        console.log(++x)
    }
}
var a = mo();
var b = mo();
a();
a();
b();

複製代碼

答案是1,2,1。
a 和 b是不一樣的兩個函數,分別保持着各自對不一樣的x的引用。

題目四

var p = [];
var A = new Function();
A.prototype = p;
var a = new A;
a.push(1);
console.log(a.length);
console.log(p.length);
複製代碼

答案:1,0。
這題要理解的一點是:

a.__proto__ === p
複製代碼

按照<<高級程序設計>>中講解的new的過程:

  • 建立一個新對象
  • 將構造函數的做用域賦給新對象(所以this就指向了這個新對象)
  • 執行構造函數中的代碼(爲這個對象添加屬性)
  • 返回新對象

咱們模仿一下new這個過程發生的事: new A =>

(funciton(){
    //第一步,把__proto__指向p(A.prototype)
    //第二步,按照p(A.prototype)的樣子創造一個對象(克隆)
    var a = Object.create(A.protype);
    A.call(a);
    return a;
})()
複製代碼

new 若是在繼承對象是沒有參數的狀況下,是能夠不加後面的括號的,編譯器會自動替你加上的。可是要記住new的沒有括號優先級是低於.的,有括號是高於();

題目五,數組降維

[1,2,3,[4,5,[6,7]]]
複製代碼

下面是原文做者提供的兩種寫法:

function fn(arr){ 
    var tempArr = Array.from(arr.join('-'));  //join()會自動添加逗號
    for(var i = 0;i<tempArr.length;i++){ 
        if(isNaN(tempArr[i])){ 
            tempArr.splice(i,1) 
        } 
    } 
    return tempArr; 
}
複製代碼
function fn(arr){
         var myArr = [];
         var fn2 = function(arr2){
               for(var i = 0;i<arr2.length;i++){
                   if(Array.isArray(arr2[i])){
                        fn2.call(null,arr2[i])
                   }
                   else{
                       myArr.push(arr2[i]);
                   }
               }
         }
         fn2(arr);
         return myArr;
       }
       fn([1,2,3,[4,5,[6,7]]]);

複製代碼

這裏再提供一種簡潔的寫法:

let flatten = arr => arr.reduce((pre,cur)=>{
	Array.isArray(cur)?pre.push(...flatten(cur)):pre.push(cur);
	return pre
},[])

複製代碼

面試

函數聲明和函數表達式有什麼區別

答:解析器有一個函數聲明提高的過程,讀取並將函數聲明添加到執行環境中,Javascript在第一遍會聲明函數並將它們放到源代碼的頂部。使其在執行任何代碼以前可用。

函數聲明既然會提高,優先級是什麼,和var比呢

答:函數提高優先級比變量提高要高,且不會被變量聲明覆蓋,可是會被變量賦值覆蓋,也會被後面的同名函數替換。

console.log(typeof(foo));   //function
function foo(){}
var foo = 5;
複製代碼
foo = 5;
console.log(typeof(foo));  //number
function foo(){}
複製代碼

函數聲明的提高爲何會比var高,編譯器幹了什麼事情

引擎在執行javascript代碼以前,會先將其進行編譯,編譯階段會找到全部聲明,並找到合適的做用域將它們關聯起來。 Javascript在第一遍會聲明函數並將它們放到源代碼的頂部 函數聲明提高的是整個函數,變量聲明提高的僅僅是var a;這部分。

函數聲明會將變量聲明覆蓋,而變量聲明只能當作重複聲明被忽略。因此函數聲明的提高比var高。(純我的理解,若有不對歡迎指出)

es6 裝飾器用過沒,是幹什麼用的(應該是es7的,反正我也沒答出來,答出來確定還繼續深的問)

裝飾類、裝飾方法或屬性。裝飾器能夠聯想到裝飾器模式:向一個現有的對象添加新的功能,同時又不改變其結構的設計模式,它是做爲現有的類的一個包裝。

es6中的擴展運算符...的實現原理

調用默認的iterator接口

<-------------------如下內容是原文做者的回答,明天接着刷,你們有好的答案之類很是歡迎提供---------------------------->

es6中的解構中的...和上面的區別

答:說真的,我也不知道啥區別,不是同樣用嗎?

[...org,name] = [1,2,3,4] 這樣的話,org裏是個啥

答:開始問的放後面是啥,我想了半天,沒敢說,我說難道後面的就沒抓到,全被org抓走了?其實不是,直接報錯了,...是rest的意思,既然是rest,那就只能放在最後啊

更新說明我還不會用,區別應該是問的es7中的解構。原理就是es6直接採用for of,也就是說,全部總有迭代器的對象都能使用擴展運算符,在es6裏說不能放前面的,可是在es7裏若是用於對象是能夠放前面的。懂了這個,上面幾題就都該會了

for of 和for in區別

答:for in 是鍵值對形式,for of 是輸出value形式,而後for of只要是配置了迭代器,都能遍歷。

this的指向問題

答:這個正常的都說了

箭頭函數中的this

答:這裏說的很差,我只說了用了箭頭函數的話,this就被傳進來了。就不須要綁定進來了。

箭頭函數中的this默認指向在定義它時,它所處的對象,而不是執行時的對象, 定義它的時候,可能環境是window

什麼是閉包(這裏答的不太好,雖然都會用啊處理的,我用相似以下代碼舉例,貌似面試官並不滿意...)

function aa(){
        var a = 1;
        return function bb(){
            console.log(a);
        }
    }
    aa()()
複製代碼

什麼是做用域

答:在進入腳本標籤編譯階段的時候就定義了各種做用域,外面的變量就在全局做用域,函數內部的就在函數的做用域裏,做用域外的函數不能訪問某個做用域裏面的東西

什麼是做用域鏈

答:在各級執行上下文建立階段的時候,就肯定了各級做用域,串起來就是做用域鏈了。好比閉包的時候外部函數出棧以後,內部函數還保留了對外部函數某個變量的引用,就是經過做用域鏈找過去的

什麼是原型

答:prototype,好像我也說不出啥,就舉個函數的寫原型的例子。 js有哪些設計模式(我說有工廠模式,構造函數模式,原型模式,面試官說這是面向對象,不過我以爲有啥區別,面向對象編程不久是要用這些設計模式嗎) 這些模式都是咋寫的,我手寫給他看

爲何要用原型

答:共享原型裏的東西給下屬繼承的對象,這樣在new的時候不用從新建立,節省內存空間

eval的缺點

答:我說了用法,就是可執行string,而後缺點沒說,沒怎麼研究,只是看了一眼用法類型的

with的缺點

答:沒用過,在網上看到過,說不要用,而後我就不用,應該會致使性能問題吧

在嚴格模式下能不能用eval

答:不能

es5和es6嚴格模式的區別

答:不知道

什麼是柯里化,舉React和Redux的例子

答:解釋了柯里化是啥,舉不出來例子,沒看過源碼啊或者是對react瞭解的不夠多

什麼是純函數

答:不產生任何交互的函數?答的很差,我說reducer應該就是個純函數,猜對了而已。

純函數是指 不依賴於且不改變它做用域以外的變量狀態 的函數純函數的概念連接

頁面和服務器之間的交互有哪幾種(ajax,websocket,不滿意)

ajax的Type有幾種(我只知道post和get)

這題我可能沒有理解... get和post的區別(我說的表象區別,url參數,安全性,大小限制,面試官不是很滿意)

與 POST 相比,GET 更簡單也更快,而且在大部分狀況下都能用。 然而,在如下狀況中,請使用 POST 請求: 沒法使用緩存文件(更新服務器上的文件或數據庫) 向服務器發送大量數據(POST 沒有數據量限制) 發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

HTTP請求頭上都有什麼信息

答:UA,HOST,其餘的我也沒說,就說還有幾個沒注意..

如何統計頁面上的按鈕被點擊了多少次

答:和服務器交互?反正也只能存服務器啊...

單頁面應用和多頁面應用的區別

答:一個跳頁面是內部的,一個跳頁面是href整頁刷新的。

哪一種更容易被SEO到,優化SEO

答:猜想是多頁面,頁面多唄...優化的不知道

上兩題補充連接

cookie和localstorage區別(我說大小,安全,有效期,貌似又不是很滿意)

JSON.stringify(大OBJ)的時候會有什麼問題 答:性能損失。

script標籤順序怎麼控制,涉及到依賴必需要有前後

答:在HTML層就控制順序唄,顯然不是他要的答案

除了直接引用script標籤,若是不用import require這樣的東西,怎麼調用其它頁面的js

答:真不知道,a.js裏除了用script標籤引用b.js

import和require的區別

答:import是靜態加載,一旦你import,內容就進來了,require是動態加載,用的時候才加載,後面又問了一些,後面就不會了

函數節流怎麼實現

答:簡單是settimeout,時間超出就執行,沒超出再進來的話就直接clear掉。面試官以爲太簡單了。

canvas 繪製原理

答:不知道

如何使用canvas拖動一個小球撞擊另一個小球,而後另一個小球被撞擊出去 答:canvas一年半沒用鐵定不記得了(總共也就2年經驗),可是說了一下實現思路

canvas 裏有不少小球時如何優化性能

答:不知道

微信小程序跳轉頁面最多能跳轉多少層 不會

RN中listview 的key值的實現原理 不會

而後還問了一些關於項目上的問題,以及如何設計一個搜索組件,須要考慮到哪些問題。 應該就這些,沒想起來的想起來再補充,感受答的很差,不少都不記得了。 三分之一的題目 好比實現原理啊,缺點啊,爲何啊,會有什麼問題啊,此類問題要麼不會,要麼答的很差 總共就這麼多,我要繼續鞏固基礎了~!!!!!!!

金三銀四,看見你們都在爲了面試而努力 特開了一個前端模擬面試題,組織了面試的羣友天天來羣裏分享面試題,講題 急思衆議,共同進步,歡迎最近在面試或者準備面試的羣友加入本羣,加羣格式: 工做年限-面試等級(初、中、高)-工做地點 (不在面試或者不許備面試或者不活躍的勿加本羣,加了也會被清理)

相關文章
相關標籤/搜索