博客 / 詳情

返回

某峯前端二階段面試題

1. JS 有哪些數據類型,它們的區別有哪些?

JS 數據類型分為基本數據類型和​引用數據類型​。

  • 基本數據類型:String、Number、Boolean、Null、Undefined、Symbol、BigInt,共 7 種,存儲在棧內存,值不可變,按值傳遞。
  • 引用數據類型:Object(包含 Array、Function、Date 等),存儲在堆內存,棧內存保存堆內存地址,值可變,按引用傳遞。

2. 數據類型檢測的方式有哪些?

  1. typeof​:檢測基本數據類型(null 會被識別為 object),引用類型除 function 外都識別為 object。
  2. instanceof​:檢測構造函數的 prototype 是否出現在實例的原型鏈上,適用於引用類型。
  3. prototype.toString.call()​:最準確的檢測方式,返回 [object 類型] 格式字符串,可識別所有數據類型。
  4. constructor​:通過實例的 constructor 屬性指向其構造函數來判斷。

3. 介紹下 Ajax

Ajax 全稱 ​Asynchronous JavaScript and XML​(異步 JavaScript 和 XML),是一種在不重新加載整個頁面的情況下,與服務器交換數據並更新部分頁面的技術。核心是 XMLHttpRequest 對象(或現代的 fetch API),實現​異步請求​,提升用户體驗。流程:創建請求對象 → 配置請求參數 → 發送請求 → 監聽狀態變化 → 處理響應數據。

4. 如何判斷一個數據是 NaN?

  1. isNaN():ES6 新增方法,僅當參數是 NaN 且類型為 Number 時返回 true,避免了全局 isNaN() 的類型轉換問題。
  2. value !== value:利用 NaN 是唯一不等於自身的值的特性,這是判斷 NaN 的可靠方法。

5. null 和 undefined 的區別

  • undefined​:表示變量已聲明但未賦值,或對象屬性不存在,是 JS 自動賦予的初始值;typeof undefined 返回 undefined。
  • null​:表示變量主動賦值為“空值”,代表一個空對象指針;typeof null 返回 object。
  • 轉換為數值時:Number(undefined) 是 NaN,Number(null) 是 0。

6. 介紹下閉包,在什麼場景下使用過?

  • 定義​:閉包是指有權訪問另一個函數作用域中變量的函數,本質是函數作用域鏈的保留。
  • 特性​:延長外部函數變量的生命週期,隔離作用域避免變量污染。
  • 使用場景​:① 封裝私有變量(如計數器函數,避免全局變量);② 防抖節流函數的實現;③ 模塊化開發中暴露特定方法。

7. 事件委託是什麼?如何確定事件源?

  • 事件委託​:利用事件冒泡機制,將子元素的事件綁定到父元素上,由父元素統一處理。優點是減少事件綁定次數、支持動態添加的子元素。
  • 確定事件源​:在事件處理函數中,通過 target(觸發事件的真實元素)獲取事件源,兼容低版本 IE 用 event.srcElement。

8. 本地存儲與 cookie 的區別

特性 本地存儲(localStorage/sessionStorage) Cookie
存儲大小 約 5MB 約 4KB
生命週期 localStorage 永久存儲,sessionStorage 會話結束失效 可設置過期時間,默認會話結束失效
與服務器交互 不隨請求發送到服務器 每次請求自動攜帶到服務器
作用域 同源頁面共享 同源且符合路徑、域名規則

9. 簡述下 ES6 的新特性

  1. 塊級作用域:let、const 關鍵字。
  2. 箭頭函數:簡化函數寫法,無自己的 this。
  3. 解構賦值:快速提取數組、對象的屬性。
  4. 模板字符串:反引號 \` 包裹,支持換行和變量插值 ${}。
  5. 類與繼承:class、extends 關鍵字,簡化原型鏈寫法。
  6. 模塊化:import/export 語法。
  7. 新增數據結構:Set、Map。
  8. 異步方案:Promise 對象。
  9. 其他:默認參數、剩餘參數 ...、擴展運算符 ... 等。

10. Let、var 和 const 的區別

特性 var let const
作用域 函數作用域/全局作用域 塊級作用域 塊級作用域
變量提升 存在,可先使用後聲明 存在暫時性死區,不可先使用 同 let
重複聲明 允許 不允許 不允許
賦值 可多次賦值 可多次賦值 聲明時必須賦值,且不可修改引用(基本類型不可改,引用類型屬性可改)

11. 數組都有哪些方法

  1. 增刪改查​:push()(尾增)、pop()(尾刪)、unshift()(頭增)、shift()(頭刪)、splice()(增刪改)、slice()(截取)。
  2. 遍歷迭代​:forEach()、map()、filter()、reduce()、some()、every()。
  3. 排序與轉換​:sort()(排序)、reverse()(反轉)、join()(轉字符串)、concat()(合併數組)。
  4. 其他​:indexOf()/lastIndexOf()(查找索引)、includes()(判斷是否包含)、find()/findIndex()(查找元素/索引)、flat()(扁平化數組)。

12. JSON 如何新增和刪除鍵值對

JSON 本質是符合格式的 JS 對象,操作方式與對象一致:

  • 新增鍵值對​:key = value 或 obj['key'] = value。
  • 刪除鍵值對​:使用 delete obj.key 或 delete obj['key']。

13. 簡述下面向對象

面向對象(OOP)是一種編程思想,核心是​封裝、繼承、多態​。

  • 封裝:將數據和操作數據的方法封裝在對象中,隱藏內部細節,暴露公共接口。
  • 繼承:子類繼承父類的屬性和方法,實現代碼複用。
  • 多態:同一方法在不同對象上有不同的表現形式(JS 中通過重寫方法實現)。

JS 是基於原型的面嚮對象語言,沒有類的概念(ES6 class 是語法糖)。

14. 普通函數與構造函數的區別

  • 命名規範​:構造函數首字母通常大寫,普通函數首字母小寫。
  • 調用方式​:構造函數用 new 關鍵字調用,普通函數直接調用。
  • 返回值​:構造函數默認返回實例對象(手動返回對象會覆蓋);普通函數無 return 時返回 undefined。
  • this ​指向​:構造函數中 this 指向新創建的實例;普通函數中 this 指向調用者(全局調用指向 window/global)。

15. 請簡述原型,原型鏈和繼承

  • 原型(prototype)​:每個函數都有 prototype 屬性,指向原型對象,原型對象包含所有實例共享的屬性和方法。
  • 原型鏈​:每個實例對象都有 proto 屬性,指向其構造函數的 prototype;當訪問實例屬性時,會依次向上查找原型對象,直到 prototype,這條鏈式結構就是原型鏈。
  • 繼承​:JS 中繼承基於原型鏈實現,子類實例的 proto 指向父類的 prototype,從而繼承父類的屬性和方法;常見方式有原型鏈繼承、構造函數繼承、組合繼承等。

16. 簡述下對 Promise 的理解以及你在什麼情況下使用過

  • Promise 理解​:Promise 是解決 JS 異步回調地獄的方案,代表一個異步操作的最終完成(或失敗)及其結果值。有三種狀態:pending(進行中)、fulfilled(已成功)、rejected(已失敗),狀態一旦改變不可逆轉。提供 then()、catch()、finally() 方法鏈式調用。
  • 使用場景​:① 異步請求(如 axios 基於 Promise 封裝,處理接口請求的成功和失敗);② 讀取文件(js 中 fs.promises 模塊);③ 多個異步操作的串行/並行處理(Promise.all()/Promise.race())。

17. 簡述下 async 的用法

async 用於聲明​異步函數​,返回值是一個 Promise 對象;await 關鍵字只能在 async 函數中使用,用於等待 Promise 執行完成,暫停函數執行直到 Promise 狀態變為 fulfilled 或 rejected。

  • 成功時:await 返回 Promise 的成功值;
  • 失敗時:需用 try/catch 捕獲異常,否則會拋出錯誤。
  • 作用:將異步代碼以同步的寫法呈現,比 Promise 鏈式調用更簡潔。

18. 簡述下 jQuery

jQuery 是一款輕量級的 JS 庫,核心思想是 ​Write Less, Do More​(寫得更少,做得更多)。它封裝了原生 JS 的 DOM 操作、事件處理、Ajax 請求等功能,解決了瀏覽器兼容性問題。特點:① 簡潔的選擇器;② 鏈式調用;③ 豐富的插件生態;④ 動畫效果便捷。但隨着 Vue、React 等框架的興起,jQuery 在現代前端開發中使用逐漸減少。

19. 什麼是 Sass、Less,為什麼使用它們

  • Sass/Less​:都是 CSS 預處理器,擴展了 CSS 的語法,增加了變量、混合、嵌套、繼承等特性,讓 CSS 更易維護和複用。Sass 後綴是 .scss(或 .sass),Less 後綴是 .less。
  • 使用原因​​:① 變量:統一管理顏色、字體等樣式屬性;② 嵌套:模擬 DOM 層級結構,增強代碼可讀性;③ 混合:複用公共樣式片段;④ 繼承:減少代碼冗餘;⑤ 模塊化:拆分樣式文件,便於維護。

20. JS 中 call()和 apply()方法的區別

call() 和 apply() 都用於改變函數執行時 this 的指向,第一個參數都是 this 要指向的對象。

  • 區別​:傳入參數的方式不同。

    • call():第一個參數是 this 指向,後續參數是​單個參數列表​,用逗號分隔。

例:fn.call(obj, arg1, arg2)

  • apply():第一個參數是 this 指向,第二個參數是​參數數組​(或類數組對象)。

例:fn.apply(obj, [arg1, arg2])

21. 為什麼會造成跨域?

跨域是指瀏覽器的同源策略限制,當一個請求的協議、域名、端口三者中任意一個與當前頁面不同,就會產生跨域。同源策略是瀏覽器的安全機制,防止不同源的頁面之間隨意訪問數據,避免 XSS、CSRF 等攻擊。

22. this 有幾種指向?

  1. 全局環境​:this 指向全局對象(瀏覽器中是 window,js 中是 global)。
  2. 函數直接調用​:非嚴格模式下 this 指向全局對象,嚴格模式下 this 是 undefined。
  3. 對象方法調用​:this 指向調用該方法的對象。
  4. 構造函數調用​:this 指向新創建的實例對象。
  5. call()**/​apply()​/**bind() ​調用​:this 指向傳入的第一個參數。
  6. 箭頭函數​:沒有自己的 this,this 指向箭頭函數定義時所在作用域的 this。
  7. 事件處理函數​:this 指向觸發事件的 DOM 元素。

23. 請説出三種減少頁面加載時間的方式

  1. 資源壓縮​:壓縮 JS、CSS、HTML 文件,減小文件體積;壓縮圖片(WebP 格式、圖片壓縮工具)。
  2. 資源緩存​:設置合理的 HTTP 緩存頭(如 Cache-Control、Expires),利用 localStorage 緩存不常變化的靜態資源。
  3. 減少 HTTP 請求​:合併 CSS/JS 文件,使用雪碧圖合併小圖標,採用懶加載加載非首屏資源。
  4. CDN 加速​:將靜態資源部署到 CDN 服務器,就近獲取資源,提高加載速度。

24. 什麼是 JSONP,工作原理是什麼?它為什麼不是真正的 Ajax?

  • JSONP​:是一種跨域請求解決方案,全稱 ​JSON with Padding​。
  • 工作原理​:利用 <script> 標籤不受同源策略限制的特性,動態創建 <script> 標籤,請求後端接口,後端返回一個函數調用的字符串,函數參數是需要的 JSON 數據,前端提前定義好該函數,從而獲取數據。
  • 不是真正的 Ajax​:Ajax 基於 XMLHttpRequest 對象實現,而 JSONP 基於 <script> 標籤的請求,不依賴 XMLHttpRequest,且只支持 GET 請求,不支持 POST 等其他請求方法。

25. 説幾種數組去重方式

  1. 利用 Set​:[...new Set(arr)],簡潔高效,ES6 推薦方法。
  2. 利用 indexOf/includes​:遍歷數組,判斷元素是否已存在於新數組中,不存在則添加。
  3. 利用 filter + indexOf​:filter((item, index) => arr.indexOf(item) === index)。
  4. 利用對象屬性唯一性​:將數組元素作為對象的鍵,避免重複。

26. 簡述下深淺拷貝,並説下如何分別實現,以及使用場景

  • 淺拷貝​:只複製對象的第一層屬性,若屬性是引用類型,複製的是地址,修改新對象會影響原對象。

    • 實現方法:assign()、擴展運算符 {...obj}、數組 slice()/concat()。
    • 使用場景:複製只有基本類型屬性的簡單對象。
  • 深拷貝​:複製對象的所有層級屬性,新對象與原對象完全獨立,修改互不影響。

    • 實現方法:parse(JSON.stringify(obj))(缺點:無法複製函數、RegExp 等)、遞歸手寫深拷貝、lodash.cloneDeep()。
    • 使用場景:複製包含引用類型屬性的複雜對象(如嵌套對象、數組)。

27. 為什麼 JS 是弱類型語言

弱類型語言的特點是​變量類型不固定,支持隱式類型轉換​。JS 中變量聲明時不需要指定類型,賦值後類型可以隨時改變;在運算時,JS 會自動將不同類型的值轉換為相同類型再計算(如 1 + '2' = '12')。與之相對的是強類型語言(如 Java),變量類型固定,必須顯式轉換類型。

28. 怎麼轉換 Less 為 CSS

  1. 使用 Less 官方編譯器​:安裝 js 後,通過 npm 安裝 less 包,執行命令 lessc styles.less styles.css 編譯。
  2. 構建工具集成​:在 Webpack/Vite 等構建工具中配置 less-loader,打包時自動將 Less 轉換為 CSS。
  3. 編輯器插件​:使用 VS Code 的 Easy LESS 插件,保存 Less 文件時自動生成對應的 CSS 文件。

29. ECharts 使用最多的是什麼?

ECharts 是百度開源的可視化圖表庫,使用最多的是​各類統計圖表的繪製​,包括:

  1. 折線圖/柱狀圖​:用於展示數據的趨勢和對比。
  2. 餅圖/環形圖​:用於展示數據的佔比情況。
  3. 地圖​:用於展示地理相關的數據分佈。
  4. 儀表盤​:用於展示關鍵指標的數值。

核心是通過配置項 option 設置圖表的數據源、樣式、交互等屬性。

30. for 循環和 map 循環有什麼區別?

  1. 返回值​:for 循環無返回值,需手動操作數組;map 循環返回一個新數組,新數組元素是原數組元素經過回調函數處理後的結果。
  2. 功能​:for 循環可用於遍歷、修改原數組、跳出循環(break/continue);map 循環主要用於​映射轉換數組​,不能中斷循環。
  3. 可讀性​:map 循環寫法更簡潔,語義化更強,適合數組的批量轉換;for 循環更靈活,適合複雜的遍歷邏輯。

31. 請寫一個簡單的類與繼承

// 父類

class Person {

constructor(name, age) {

this.name = name;

this.age = age;

}

sayHello() {

console.log(`我是${this.name},今年${this.age}歲`);

}

}

// 子類繼承父類

class Student extends Person {

constructor(name, age, grade) {

super(name, age); // 調用父類構造函數

this.grade = grade;

}

study() {

console.log(`${this.name}在${this.grade}年級學習`);

}

}

// 實例化

const stu = new Student('小明', 12, 6);

stu.sayHello(); // 我是小明,今年12歲

stu.study(); // 小明在6年級學習

32. 同步與異步的區別?阻塞與非阻塞的區別?

同步與異步

  • 同步​:代碼按順序執行,前一個任務完成後才執行下一個任務,主線程會被阻塞。例:普通函數調用、alert()。
  • 異步​:任務不會阻塞主線程,發起後繼續執行後續代碼,任務完成後通過回調/事件通知結果。例:setTimeout、Ajax 請求。

阻塞與非阻塞

  • 阻塞​:線程執行任務時,必須等待任務完成才能繼續執行其他操作,線程處於等待狀態。
  • 非阻塞​:線程執行任務時,若任務未完成,可立即返回去執行其他操作,無需等待,通過輪詢或回調獲取任務結果。
  • 關係​:同步 ≠ 阻塞,異步 ≠ 非阻塞,它們是不同維度的概念(同步異步描述任務的執行順序,阻塞非阻塞描述線程的狀態)。

33. HTTP 是什麼?有什麼特點?

HTTP 全稱 ​HyperText Transfer Protocol​(超文本傳輸協議),是用於在客户端和服務器之間傳輸數據的應用層協議,基於 TCP/IP 協議。

  • 特點​:

    1. 無狀態​:協議本身不記錄客户端的請求狀態,每次請求都是獨立的(可通過 Cookie/Session 保持狀態)。
    2. 無連接​:HTTP 1.0 中,每次請求都要建立新的 TCP 連接,請求完成後斷開;HTTP 1.1 支持持久連接(Keep-Alive)。
    3. 簡單快速​:請求格式簡單,客户端向服務器發送請求方法和路徑,服務器返回狀態碼和數據。
    4. 靈活​:支持多種數據類型(如文本、圖片、視頻等)。

34. HTTP 協議和 HTTPS 的區別

特性 HTTP HTTPS
安全性 明文傳輸,數據易被竊取、篡改 加密傳輸(SSL/TLS 協議),數據安全
端口 默認 80 默認 443
證書 無需證書 需要 CA 頒發的 SSL 證書
性能 速度快,無加密解密開銷 速度稍慢,有加密解密過程
資源消耗

35. 原型和繼承,prototype,call 和 apply 繼承的區別

  • 原型繼承​:將子類的 prototype 指向父類的實例,子類實例可繼承父類原型上的屬性和方法。缺點:父類的引用類型屬性會被所有子類實例共享;無法向父類構造函數傳參。
  • call/apply 繼承​:在子類構造函數中調用父類構造函數,通過 call()/apply() 改變父類 this 指向子類實例,實現父類實例屬性的繼承。缺點:無法繼承父類原型上的方法。
  • 組合繼承​:結合原型繼承和 call/apply 繼承,既繼承父類實例屬性,又繼承父類原型方法,是最常用的繼承方式。

36. 説幾種數組和字符串的方法及他們的作用

數組方法

  1. map():遍歷數組,返回新數組,元素為回調函數處理結果。
  2. filter():過濾數組元素,返回符合條件的新數組。
  3. reduce():累計計算數組元素,返回最終結果(如求和、求積)。
  4. find():返回數組中第一個符合條件的元素。

字符串方法

  1. split():將字符串按分隔符分割為數組。
  2. indexOf()/includes():查找子字符串是否存在,返回索引或布爾值。
  3. substring()/slice():截取字符串的指定部分。
  4. replace():替換字符串中的指定內容。

37. 箭頭函數與普通函數的區別

  1. this ​指向​:箭頭函數無自己的 this,指向定義時所在作用域的 this;普通函數 this 指向調用者。
  2. 構造函數​:箭頭函數不能作為構造函數,不能用 new 調用;普通函數可以。
  3. 參數​:箭頭函數沒有 arguments 對象,可使用剩餘參數 ...args;普通函數有 arguments。
  4. 原型​:箭頭函數沒有 prototype 屬性;普通函數有。
  5. 寫法​:箭頭函數寫法更簡潔,適合回調函數;普通函數寫法更靈活。

38. 什麼是 JS 內存泄露

內存泄露是指​程序中已不再使用的內存沒有被及時釋放,導致內存佔用越來越高,最終影響程序性能甚至崩潰​。JS 中常見的內存泄露場景:

  1. 意外的全局變量(如未聲明的變量)。
  2. 閉包導致的變量未釋放。
  3. 未清除的定時器/事件監聽器。
  4. DOM 元素被刪除但仍有引用(如變量保存了已刪除的 DOM 節點)。

39. 如何對網站的文件和資源進行優化

  1. 靜態資源優化​:壓縮 JS/CSS/HTML,圖片格式轉換(WebP)、圖片懶加載、雪碧圖合併小圖標。
  2. 資源加載優化​:使用 CDN 加速,預加載關鍵資源(preload),預解析 DNS(dns-prefetch)。
  3. 代碼優化​:減少 HTTP 請求,合併文件;刪除無用代碼(Tree Shaking);延遲加載非首屏腳本。
  4. 緩存優化​:設置強緩存和協商緩存,利用 localStorage 緩存靜態數據。
  5. 服務器優化​:啓用 Gzip/Brotli 壓縮,使用 HTTP/2 協議(多路複用)。

40. 簡述 Ajax 的執行過程以及常見的 HTTP 狀態碼

Ajax 執行過程

  1. 創建 XMLHttpRequest 對象​:const xhr = new XMLHttpRequest()。
  2. 配置請求參數​:open(method, url, async)(method:請求方法;url:請求地址;async:是否異步)。
  3. 設置響應處理函數​:onreadystatechange = function() {},監聽 readyState 變化。
  4. 發送請求​:send(data)(POST 請求需傳遞數據)。
  5. 處理響應​:當 readyState === 4 且 status === 200 時,獲取響應數據 responseText。

常見 HTTP 狀態碼

  • 2xx 成功​:200(請求成功)、201(創建資源成功)。
  • 3xx 重定向​:301(永久重定向)、302(臨時重定向)、304(資源未修改,使用緩存)。
  • 4xx 客户端錯誤​:400(請求參數錯誤)、401(未授權)、403(禁止訪問)、404(資源不存在)。
  • 5xx 服務器錯誤​:500(服務器內部錯誤)、503(服務器不可用)。

41. 預加載和懶加載的區別,預加載在什麼時間合適

區別

  • 預加載​:提前加載未來可能需要的資源(如圖片、JS 文件),加載完成後緩存,當用户需要時直接從緩存讀取,提升體驗。主動加載,會增加首屏加載時間。
  • 懶加載​:延遲加載非首屏資源,只有當資源進入可視區域時才加載,減少首屏加載時間,提升頁面加載速度。被動加載,適用於圖片、視頻等大量靜態資源。

預加載合適的時間

預加載應在首屏資源加載完成後進行,避免搶佔首屏資源的帶寬,影響首屏渲染速度。可通過 window.onload 事件觸發,或在頁面空閒時(requestIdleCallback)執行。

42. jQuery 選擇器有哪些?

jQuery 選擇器基於 CSS 選擇器,分為以下幾類:

  1. 基本選擇器​:ID 選擇器($('#id'))、類選擇器($('.class'))、標籤選擇器($('div'))、通配符選擇器($('*'))。
  2. 層級選擇器​:後代選擇器($('parent child'))、子元素選擇器($('parent > child'))、相鄰兄弟選擇器($('prev + next'))。
  3. 過濾選擇器​:基本過濾(:first、:last、:eq(index))、內容過濾(:contains(text))、可見性過濾(:visible、:hidden)。
  4. 屬性選擇器​:$('[attr]')、$('[attr=value]')。

43. jQuery 插入節點的方法

  1. 內部插入​:

    • append():在元素內部末尾插入節點。
    • prepend():在元素內部開頭插入節點。
  2. 外部插入​:

    • after():在元素外部後面插入節點。
    • before():在元素外部前面插入節點。
  3. 替換節點​:replaceWith():用新節點替換原節點。
  4. 包裹節點​:wrap():用指定節點包裹每個匹配元素。

44. Get 和 Post 區別

特性 GET POST
請求參數 拼接在 URL 後,可見 放在請求體中,不可見
數據長度 受 URL 長度限制,較小 無限制,可傳輸大量數據
安全性 低,參數暴露在 URL 高,參數隱藏在請求體
緩存 可被瀏覽器緩存 不可被緩存
冪等性 冪等(多次請求結果相同) 非冪等(多次請求可能產生不同結果)
用途 讀取數據 提交/修改數據

45. 什麼是 CSRF 攻擊

CSRF 全稱 ​Cross-Site Request Forgery​(跨站請求偽造),是一種網絡攻擊手段。攻擊者誘導用户在已登錄目標網站的情況下,訪問惡意網站,利用用户的登錄狀態向目標網站發送偽造的請求,從而執行非用户意願的操作(如轉賬、修改密碼)。防禦措施:① 驗證 Referer 字段;② 使用 CSRF Token;③ 驗證碼驗證。

46. 如何遍歷一個多維數組?

  1. 遞歸遍歷​:遍歷數組元素,若元素是數組則遞歸調用遍歷函數,否則處理元素。

function traverse(arr) {

arr.forEach(item => {

if (Array.isArray(item)) {

traverse(item);

} else {

console.log(item);

}

});

}


  1. 扁平化後遍歷​:用 flat() 方法將多維數組扁平化為一維數組,再遍歷。

const arr = [1, [2, [3, 4]]];

arr.flat(Infinity).forEach(item => console.log(item));


47. Axios 的特性?

Axios 是基於 Promise 的 HTTP 客户端,支持瀏覽器和 Node.js,核心特性:

  1. 支持 Promise API,可鏈式調用。
  2. 攔截請求和響應(請求攔截器處理 token,響應攔截器統一處理錯誤)。
  3. 轉換請求和響應數據(如自動轉換 JSON 數據)。
  4. 取消請求。
  5. 防止 CSRF 攻擊。
  6. 客户端支持防禦 XSRF。
  7. 支持多種請求方法(GET、POST、PUT、DELETE 等)。

48. 在地址欄輸入一個 URL,到頁面呈現出來,中間發生了什麼?

  1. DNS 解析​:將域名轉換為對應的 IP 地址。
  2. 建立 TCP 連接​:客户端與服務器通過三次握手建立連接(HTTP/1.1 默認為持久連接)。
  3. 發送 HTTP 請求​:客户端向服務器發送請求行、請求頭、請求體。
  4. 服務器處理請求​:服務器解析請求,處理業務邏輯,生成響應數據。
  5. 服務器返回響應​:服務器向客户端發送響應行、響應頭、響應體(HTML 等資源)。
  6. 關閉 TCP 連接​:通過四次揮手關閉連接(若開啓 Keep-Alive 則保持連接)。
  7. 瀏覽器解析渲染頁面​:

    • 解析 HTML 生成 DOM 樹;
    • 解析 CSS 生成 CSSOM 樹;
    • 結合 DOM 樹和 CSSOM 樹生成渲染樹;
    • 佈局(Layout):計算元素的位置和大小;
    • 繪製(Paint):將渲染樹繪製到屏幕上。

49. 異步操作的解決方案

  1. 回調函數​:最基礎的方案,將異步操作的結果處理邏輯傳入回調函數,但容易導致回調地獄。
  2. Promise​:解決回調地獄,通過 then()/catch() 鏈式調用,支持多個異步操作的串行/並行處理。
  3. async/await​:基於 Promise 的語法糖,以同步寫法實現異步操作,代碼更簡潔易讀。
  4. Generator 函數​:通過 yield 暫停函數執行,next() 恢復執行,可實現異步流程控制(較少使用)。

50. map 和 forEach 的區別

特性 map forEach
返回值 返回新數組,元素為回調處理結果 無返回值(返回 undefined)
功能 映射轉換數組,適合生成新數組 遍歷數組,適合執行操作(如打印、修改原數組)
中斷循環 無法中斷,必須遍歷所有元素 無法中斷(無 break/continue)
性能 稍慢(需創建新數組) 稍快(無新數組創建)

51. TCP 和 UDP 的區別

特性 TCP UDP
連接性 面向連接(三次握手建立連接) 無連接(直接發送數據)
可靠性 可靠傳輸,保證數據有序、不丟失 不可靠傳輸,不保證數據到達
傳輸方式 流式傳輸,數據無邊界 數據包傳輸,數據有邊界
擁塞控制 有擁塞控制和流量控制 無擁塞控制
速度 較慢 較快
用途 文件傳輸、網頁加載、郵件發送 視頻直播、語音通話、實時遊戲

52. BOM 和 DOM 的區別

  • DOM​:全稱 ​Document Object Model​(文檔對象模型),是 HTML/XML 文檔的編程接口,將文檔解析為樹形結構,提供操作元素、屬性、事件的方法(如 getElementById())。核心是 document 對象。
  • BOM​:全稱 ​Browser Object Model​(瀏覽器對象模型),是與瀏覽器窗口交互的接口,提供操作瀏覽器窗口、地址欄、歷史記錄等的方法(如 open()、location.href)。核心是 window 對象,DOM 是 BOM 的一部分。

53. 簡述下 Git 操作

Git 是分佈式版本控制系統,常用操作:

  1. 初始化倉庫​:git init。
  2. 克隆倉庫​:git clone <url>。
  3. 文件操作​:git add <file>(添加到暫存區)、git commit -m "message"(提交到本地倉庫)。
  4. 分支操作​:git branch(查看分支)、git branch <name>(創建分支)、git checkout <name>(切換分支)、git merge <name>(合併分支)。
  5. 遠程操作​:git remote add origin <url>(關聯遠程倉庫)、git push -u origin master(推送代碼)、git pull(拉取代碼)。
  6. 版本回退​:git log(查看提交記錄)、git reset --hard <commit-id>(回退到指定版本)。

54. 什麼是 Node.js?

Node.js 是基於 Chrome V8 引擎的 ​JavaScript 運行時環境​,讓 JS 可以脱離瀏覽器運行在服務器端。特點:

  1. 非阻塞 I/O​:處理高併發請求性能優異。
  2. 事件驅動​:基於事件循環機制,異步處理請求。
  3. 豐富的模塊生態​:通過 npm 管理大量第三方模塊。
  4. 跨平台​:支持 Windows、Linux、macOS 等系統。

用途:搭建後端服務器、開發 CLI 工具、構建前端工程化工具(如 Webpack)。

55. 遍歷數組,遍歷對象,遍歷字符串的方法都有哪些?哪些可以打斷?

遍歷數組

  1. 可打斷的方法​:for 循環(break/continue)、..of 循環(break/continue)。
  2. 不可打斷的方法​:forEach()、map()、filter()、reduce()。

遍歷對象

  1. ..in:遍歷對象的可枚舉屬性(包括原型鏈上的屬性),可通過 break 打斷。
  2. keys()/Object.values()/Object.entries():返回數組後遍歷,可結合 for 循環打斷。

遍歷字符串

  1. 可打斷的方法​:for 循環、..of 循環。
  2. 不可打斷的方法​:split('').forEach()。

56. 迴流和重繪

  • 迴流(Reflow)​:當元素的佈局屬性發生變化(如寬高、位置、DOM 結構),瀏覽器需要重新計算元素的幾何屬性和位置,重新構建渲染樹,這個過程叫回流。迴流代價較高,會觸發重繪。
  • 重繪(Repaint)​:當元素的樣式屬性發生變化(如顏色、背景色),但不影響佈局時,瀏覽器只需重新繪製元素外觀,這個過程叫重繪。重繪代價低於迴流。
  • 觸發迴流的操作​:添加/刪除 DOM 元素、改變元素尺寸、改變窗口大小、offsetWidth/offsetHeight 等屬性的讀取。
  • 優化​:減少迴流次數(如批量修改樣式、使用 documentFragment 批量添加 DOM)。

57. 節流和防抖

  • 防抖(Debounce)​:觸發事件後,在指定時間內沒有再次觸發事件,才執行回調函數;若在指定時間內再次觸發,則重新計時。適用於搜索框輸入聯想、窗口大小調整等場景。
function debounce(fn, delay) {

let timer = null;

return function(...args) {

clearTimeout(timer);

timer = setTimeout(() => fn.apply(this, args), delay);

};

}

  • 節流(Throttle)​:觸發事件後,每隔指定時間執行一次回調函數,在指定時間內多次觸發只執行一次。適用於滾動加載、鼠標移動、按鈕點擊等場景。
function throttle(fn, interval) {

let lastTime = 0;

return function(...args) {

const now = Date.now();

if (now - lastTime >= interval) {

fn.apply(this, args);

lastTime = now;

}

};

}

58. 宏任務和微任務

宏任務和微任務是 JS 異步任務的分類,事件循環中執行順序為:​先執行同步代碼 → 執行所有微任務 → 執行一個宏任務 → 再執行所有微任務​,以此循環。

  • 宏任務(Macrotask)​:執行時間較長的任務,包括 setTimeout、setInterval、I/O、UI 渲染、script 整體代碼。
  • 微任務(Microtask)​:執行時間較短的任務,包括 then()/catch()/finally()、async/await、queueMicrotask()、MutationObserver。

59. 什麼是裝飾器?

裝飾器(Decorator)是一種​設計模式​,用於在不修改原函數/類代碼的前提下,動態地為其添加額外功能。ES7 中提出了裝飾器語法(目前是提案,需通過 Babel 編譯)。

  • 類裝飾器​:用於裝飾類,修改類的行為。
  • 方法裝飾器​:用於裝飾類的方法,修改方法的執行邏輯。
  • 用途:日誌記錄、性能監控、權限校驗等。例如:用裝飾器記錄函數的執行時間。

60. 什麼是迭代器?

迭代器(Iterator)是一種接口,為不同的數據結構提供統一的遍歷機制。任何數據結構只要部署了 Iterator 接口,就可以通過 for...of 循環遍歷。

  • 迭代器的特性​:有一個 next() 方法,每次調用返回一個對象 { value: 當前值, done: 是否遍歷完成 }。
  • 原生支持迭代器的數據結構​:數組、字符串、Set、Map。
  • 自定義迭代器​:通過 iterator 屬性為對象部署迭代器接口。

61. 什麼是前端微服務?

前端微服務是借鑑後端微服務的思想,將​大型前端應用拆分為多個獨立的、可獨立開發、測試、部署的小型應用​,每個小型應用稱為一個“微應用”。

  • 核心特點​:

    1. 獨立部署:每個微應用可單獨發佈,不影響其他微應用。
    2. 技術棧無關:不同微應用可使用不同的前端框架(如 Vue、React)。
    3. 共享基礎資源:共享公共組件、工具庫、狀態管理等。
    4. 運行時集成:通過主應用(基座)加載微應用,實現頁面跳轉和通信。
  • 實現方案​:基於 qiankun、single-spa 等框架。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.