前端開發常見筆試/面試題總結 -- JavaScript篇

前一篇文章是關於HTML/CSS面試題的,連接見這裏,今天聊一聊一些高頻出現的JavaScript面試題。ios

對原型和原型鏈是如何理解的?

  1. JavaScript由對象構成,每個對象(除null外)都和另外一個對象相關聯(經過__proto__屬性),「另外一個對象」就是原型。即任何一個對象都有原型這個屬性。
  2. 繼承原型依靠"原型鏈"(prototype chain)模式來實現繼承
  3. 全部 JavaScript 對象都從原型 (prototype) 繼承屬性和方法,能夠嘗試打印一下String.prototype、Array.prototype ...
  4. 日期對象繼承自 Date.prototype。數組對象繼承自Array.prototype。函數對象繼承自Function.prototype。日期對象、數組對象和函 數對象都繼承自Object.prototype,其位於原型繼承鏈的頂端
  5. 能夠用 object.prototype.name = value 修改本身建立的原型,不要修改 JavaScript 標準對象的原型

JavaScript解釋器的執行順序和原理

  • Js引擎(瀏覽器)將執行的任務分爲同步任務異步任務,同步任務就是在主線程上按順序執行,上一個任務不完成,下一個任務就沒法進行,是線程阻塞的。而異步任務則處於「任務隊列」中,不會形成阻塞線程。
  • 運行機制:程序開始後,主線程先執行同步任務,碰到異步任務先放到任務隊列(TO DO LIST,又稱事件隊列)中,如setTimeout(),而後繼續執行。等同步任務執行完畢,JS引擎便去查看任務隊列有沒有能夠執行的異步任務,有的話,將異步任務轉爲同步任務,開始執行,執行完該同步任務後繼續查看任務隊列,這個過程是一直循環的,也就是所謂的事件循環。(經過任務隊列,單線程的JS實現了所謂的"多線程")
  • 加入宏任務,微任務:JS解釋器執行順序爲,同步任務(先執行宏任務,在執行微任務),遍歷異步隊列,執行異步任務。面試

    1. 宏任務:由宿主環境發起,如setTimeoutsetInterval
    2. 微任務:由JavaScript引擎發起的,如 Promise.then()

基礎類型和引用類型在存儲方式和拷貝上的區別?

存儲方式ajax

  • 基本數據類型:key和value存儲在棧內存中
  • 引用數據類型:key存在棧內存中,value存在於堆內存中,可是棧內存會提供一個引用的地址指向堆內存中的值

拷貝:json

  • 深拷貝與淺拷貝的概念只存在於引用數據類型
  • 淺拷貝只會將對象的各個屬性進行依次複製,並不會進行遞歸複製,也就是說只會賦值目標對象的第一層屬性。深拷貝不一樣於淺拷貝,它不僅拷貝目標對象的第一層屬性,而是遞歸拷貝目標對象的全部屬性。
  • 淺拷貝對於目標對象第一層爲基本數據類型的數據,就是直接賦值,即「傳值」;而對於目標對象第一層爲引用數據類型的數據,就是直接賦存於棧內存中的堆內存地址,即「傳址」,並無開闢新的棧,也就是複製的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另外一個對象的屬性也會改變。而深複製則是開闢新的棧,兩個對象對應兩個不一樣的地址,修改一個對象的屬性,不會改變另外一個對象的屬性。

什麼是閉包,如何利用閉包?

閉包是指有權訪問父做用域中的變量的函數
用處: 能夠實現封裝,屬性私有化 / 防止污染全局變量axios

數組的for、forEach和map的區別是什麼

  • for循環能夠中途跳出,而 forEach 不能夠,break 命令或 return 命令都不能生效
  • 相比普通的for循環,forEach的優點在於對稀疏數組的處理,會跳過數組中的空位
  • forEach改變原數組,map不改變原數組而是返回一個新數組

如何寫一個數據請求?

  • 傳統的AJAX請求,利用XMLHttpRequest發送請求,獲取數據。爲了兼容性,應該用jQuery的AJAX
$.ajax({
      method: 'POST',
      url: '/api',
      data: { username: 'admin', password: 'root' }
    })
    .done(function(msg) {
      alert( 'Data Saved: ' + msg );
    });
  • 在ES6中,新增了 fetch 方法:
fetch(url, {
      method : 'get',
    })
    .then(response => response.json())
    .then(res => console.log(res))
    .catch(err => console.log("Oops, error", err))
  • 利用第三方axios庫:
axios.get('/user', {
      params: {
        ID: 12345
      }
    })
    .then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    });

用JavaScript代碼實現斐波那契數列

斐波那契數列的排列是:1,1,2,3,5,8,13,21,34,55,89,144 ...
輸入任意的index,返回對應位置的斐波那契數
實現以下:segmentfault

getFibonacci = (n) => {
  let e1 = 0;
  let e2 = 1;
  let target = 0;
  for(let i=1; i<=n; i++){
    e1 = e2;
    e2 = target;
    target = e2 + e1;
  }
  return target;
}

談談你對MVC、MVP和MVVM的理解,具體在寫代碼中的體驗

Model-View-Controller:M(數據保存)、V(用戶界面)、C(業務邏輯)api

  • View 傳送指令到 Controller
  • Controller 完成業務邏輯後,要求 Model 改變狀態
  • Model 將新的數據發送到 View,用戶獲得反饋
  • 全部的通訊都是單向的

Model-View-Presenter數組

  • 各部分之間的通訊,都是雙向的
  • View 與 Model 不發生聯繫,都經過 Presenter 傳遞
  • View 很是薄,不部署任何業務邏輯,稱爲"被動視圖"(Passive View),即沒有任何主動性,而Presenter很是厚,全部邏輯都部署在那裏

Model-View-ViewModel瀏覽器

  • 基本上與 MVP 模式徹底一致,只是把Presenter變成了ViewModel

MVVM的優勢多線程

  1. 雙向綁定,當Model變化時,View和ViewModel會自動更新,保持了數據一致性
  2. 簡化了控制器
  3. View的功能進一步強化,能夠像Model同樣有本身的ViewModel
  4. 能夠對View或ViewController的數據處理部分抽象出來。減輕Model的負擔

MVVM的缺點

  1. 數據綁定使得bug很難被調試
  2. 雙向綁定不利於代碼重用
相關文章
相關標籤/搜索