前端面試小記

yellowlemon發表於2017-03-14

太久沒有面試過了,第一次難免有點緊張,今天遇到的面試問題,大多數都遇到過,卻因為沒有充分準備,而沒有答好,以後一定好好準備才行。

下面記錄一下今天的面試問題,加深印象:

  1. 介紹一下JS的資料型別?

    簡單型別:StringNumberBooleanNullUndefined
    複雜型別:Object
    ES6新增型別:Symbol(感謝TimeTraveler指出)
    &
    擴充套件:

    1. null與undefined有什麼區別
      答:null 表示一個物件被定義了,值為“空值”,而undefined 表示不存在這個值。
      正因為這個原因,所以使用typeof判斷是,null返回的是object,而undefined返回的是undefined。(判斷兩者時需要使用===嚴格判斷)
    2. Boolean型別在進行判斷的時候設定為 0、-0、null、""、false、undefined 或 NaN,則該物件設定為 false。否則設定為 true(即使 value 引數是字串 "false")
  2. 如何通過JS判斷一個陣列?

    1. instanceof方法
      instanceof 運算子是用來測試一個物件是否在其原型鏈原型建構函式的屬性。
      var arr = []; 
      arr instanceof Array; // true複製程式碼
    2. constructor方法
      constructor 屬性返回對建立此物件的陣列函式的引用,就是返回物件相對應的建構函式。
      var arr = []; 
      arr.constructor == Array; //true複製程式碼
    3. 特性判斷法
      利用判斷陣列獨有的lengthsplice方法,但是這是不靠譜的,因為物件也能新增方法和屬性。那怎麼辦了,有一個辦法,可以利用陣列的length屬性沒法列舉來判斷。
      function isArray(object){
            return  object && typeof object==='object' &&    
            typeof object.length==='number' &&  
            typeof object.splice==='function' &&    
             //判斷length屬性是否是可列舉的 對於陣列 將得到false  
            !(object.propertyIsEnumerable('length'));
      }複製程式碼
    4. 最簡單的方法
      這種寫法,是 jQuery 正在使用的,淘寶的 kissy 也是使用這種方式。
      Object.prototype.toString.call(value) == '[object Array]'
      // 利用這個方法,可以寫一個返回資料型別的方法
      var isType = function (obj) {
           return Object.prototype.toString.call(obj).slice(8,-1); 
      }複製程式碼
    5. ES5新增方法isArray()
      var a = new Array(123);
      var b = new Date();
      console.log(Array.isArray(a)); //true
      console.log(Array.isArray(b)); //false複製程式碼
      &
      擴充套件:
      1. 使用instaceofconstrucor,被判斷的array必須是在當前頁面宣告的。比如,一個頁面(父頁面)有一個框架,框架中引用了一個頁面(子頁面),在子頁面中宣告瞭一個array,並將其賦值給父頁面的一個變數,這時判斷該變數,Array == object.constructor;會返回false
      2. 最簡單的方法,在IE6下判斷nullundefined,有一些bug,判斷undefinednull均為Object,(並不是bug,是在ES3的標準下返回的就為Object)
  3. 談一談letvar的區別?

    let為ES6新新增申明變數的命令,它類似於var,但是有以下不同:

    1. let命令不存在變數提升,如果在let前使用,會導致報錯
    2. 暫時性死區,如果塊區中存在letconst命令,就會形成封閉作用域
    3. 不允許重複宣告,因此,不能在函式內部重新宣告引數
  4. mapforEach的區別?

    因為平時基本只用forEach,所以這個很尷尬,索性就把新增的陣列方法都刷一遍吧。

    1. forEach方法,是最基本的方法,就是遍歷與迴圈,預設有3個傳參:分別是遍歷的陣列內容item、陣列索引index、和當前遍歷陣列Array。另外,除去第一個必須的回撥函式引數,還可以接受一個上下文引數(改變回撥函式的this指向);並且forEach不會遍歷空元素。
    2. map方法,基本用法與forEach一致,但是不同的,它會返回一個新的陣列,所以在callback需要有return值,如果沒有,會返回undefined。(從字面理解,map就是對映的意思)
    3. filter方法,用法和map很相似,從字面理解,就是過濾、篩選的意思。但是函式的callback需要返回布林值truefalse,並且返回值只需要為弱等==即可。
    4. some 方法,對陣列中每一項執行指定函式,如果該函式對任一項返回true,則返回true。(一旦遇到true,就會中斷迴圈,返回true,類似於||判斷)
    5. every方法,對陣列中的每一項執行給定函式,如果該函式對每一項返回true,則返回true。(一旦遇到false,就會中斷迴圈,返回false,類似於&&判斷)
    6. indexOf方法,與字串中的indexOf類似,返回陣列索引值,如果沒有匹配,則會返回-1,第二個引數為可選,表示從當前位置開始搜尋。
    7. lastIndexOf方法,與indexOf相似,只是是從陣列的末尾開始查詢,而第二個引數的預設值是array.length - 1
    8. reduce方法,字面意思應該是‘減少’,但是實際是‘遞迴’的意思。實際就是應用一個函式針對陣列的兩個值(從左到右),以減至一個值。它的callback接收4個引數:之前值(上一次迴圈返回的值)、當前值、索引值以及陣列本身。initialValue引數可選,表示初始值。
    9. reduceRight方法,與reduce方法類似,只是從陣列的末尾開始實現。
  5. 談一談你理解的函數語言程式設計?

    what?函式程式設計就是函式程式設計啊,還有什麼理解??
    現在查了一下,才知道,原來沒有那麼簡單!!!
    簡單說,"函數語言程式設計"是一種"程式設計正規化"(programming paradigm),也就是如何編寫程式的方法論。
    它具有以下特性:閉包和高階函式、惰性計算、遞迴、函式是"第一等公民"、只用"表示式",不用"語句"(都會有返回值)、沒有"副作用"、不修改狀態、引用透明性。
    具體的特性代表了什麼,我還要好好研究一下!!

  6. 談一談箭頭函式與普通函式的區別?

    平時用的很爽,但是還真沒有考慮過這個問題!!

    1. 箭頭函式使得表達更加簡潔。(這個是廢話)
    2. 函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件。
    3. 不可以當作建構函式,也就是說,不可以使用new命令,否則會丟擲一個錯誤。
    4. 不可以使用arguments物件,該物件在函式體內不存在。如果要用,可以用Rest引數代替。
    5. 不可以使用yield命令,因此箭頭函式不能用作Generator函式。
  7. 談一談函式中this的指向吧?

    this的指向在函式定義的時候是確定不了的,只有函式執行的時候才能確定this到底指向誰,實際上this的最終指向的是那個呼叫它的物件。

    《javascript語言精髓》中大概概括了4種呼叫方式:

    1. 方法呼叫模式
    2. 函式呼叫模式
    3. 構造器呼叫模式
    4. apply/call呼叫模式

    特別補充:

    1. 在構造器呼叫時,如果加入了return並且return了一個物件,this會指向這個return的物件。
    2. 為什麼構造器時this會指向new的物件?
      var p = new Emp();
      // 過程模擬,new關鍵字會建立一個空的物件,然後會自動呼叫一個函式apply方法,將this指向這個空物件,這樣的話函式內部的this就會被這個空的物件替代。
      var p = {};
      Emp.apply(p);
      p.__proto__=Emp.prototype;複製程式碼
  8. 談一談閉包吧?

    「閉包」,是指那些能夠訪問獨立(自由)變數的函式 (變數在本地使用,但定義在一個封閉的作用域中)。換句話說,這些函式可以“記憶”它被建立時候的環境。特性:

    1. 函式巢狀函式
    2. 函式內部可以引用外部的引數和變數
    3. 引數和變數不會被垃圾回收機制回收
  9. 非同步程式設計的實現方式?

    1. 回撥函式:
      • 優點:簡單、容易理解
      • 缺點:不利於維護,程式碼耦合高
    2. 事件監聽(採用時間驅動模式,取決於某個事件是否發生):
      • 優點:容易理解,可以繫結多個事件,每個事件可以指定多個回撥函式
      • 缺點:事件驅動型,流程不夠清晰
    3. 釋出/訂閱(觀察者模式):
      • 類似於事件監聽,但是可以通過‘訊息中心’,瞭解現在有多少釋出者,多少訂閱者。
    4. Promise物件
      • 優點:可以利用then方法,進行鏈式寫法;可以書寫錯誤時的回撥函式;
      • 缺點:編寫和理解,相對比較難
    5. Generator函式
      • 優點:函式體內外的資料交換、錯誤處理機制
      • 缺點:流程管理不方便
    6. async函式
      • 優點:內建執行器、更好的語義、更廣的適用性、返回的是Promise、結構清晰。
      • 缺點:錯誤處理機制

相關文章