50 道高頻 JavaScript 面試題,從基礎到進階 (附答案)

在前端面試中,JavaScript 一直是重中之重。它不僅是一門腳本語言,更是現代 Web 開發的核心技術。無論是頁面交互、異步處理,還是框架與庫的運行機制,幾乎都離不開對 JavaScript 的深刻理解。
許多開發者在面試前,常常困惑于:“面試官會問哪些題?”、“哪些知識點最容易被忽略?”、“怎么才能答得有條理又有深度?”。
今天我為大家整理了 50 道高頻 JavaScript 面試題,涵蓋基礎語法、ES6 特性、異步編程、性能優化、瀏覽器機制等核心知識點,并附上簡明答案,希望能幫助你快速梳理思路,查漏補缺。
無論你是初入職場的新人,還是準備跳槽的前端工程師,都能在這里找到有價值的內容。
1. JavaScript 有哪些數據類型?
原始類型:string, number, boolean, null, undefined, symbol, bigint引用類型:object, array, function, date, regexp
2. null 和 undefined 的區別?
undefined表示變量聲明了但未賦值。null表示“空對象”,是人為賦的空值。
3. == 和 === 的區別?
==會進行類型轉換后再比較。===嚴格比較,不做類型轉換。
4. typeof null 的結果是什么?為什么?
結果是 object。這是 JavaScript 歷史遺留的 bug。
5. isNaN 和 Number.isNaN 的區別?
isNaN("abc") // true,因為會先轉型。Number.isNaN("abc") // false,不會強制轉型。
6. let、const 和 var 的區別?
var有變量提升、函數作用域。let無提升、塊級作用域。const聲明常量,不能修改引用指向。
7. 什么是暫時性死區(TDZ)?
使用 let/const 聲明的變量,在初始化前不能訪問,否則會報錯。
8. 什么是事件冒泡和捕獲?
- 捕獲:從
window → document → body → … → target。 - 冒泡:從
target → … → body → document → window。默認事件執行冒泡階段。
9. 什么是事件委托?
利用冒泡機制,把子元素的事件綁定到父元素上,提高性能。
10. 什么是閉包?
閉包是函數和其詞法作用域的組合,常用于 數據隱藏、模塊化、回調函數。
11. 什么是原型和原型鏈?
- 每個對象都有
__proto__,指向其構造函數的prototype。 - 原型鏈是對象查找屬性的機制,最終指向
Object.prototype。
12. new 操作符的原理?
- 創建一個空對象。
- 綁定原型。
- 執行構造函數。
- 返回對象。
13. call、apply 和 bind 的區別?
call:立即執行,參數逐個傳入。apply:立即執行,參數以數組傳入。bind:返回新函數,不立即執行。
14. 什么是深拷貝與淺拷貝?
- 淺拷貝:只拷貝第一層(
Object.assign、展開運算符)。 - 深拷貝:遞歸拷貝所有層級(
structuredClone、JSON.parse(JSON.stringify(obj)))。
15. 什么是節流和防抖?
- 防抖(debounce):事件觸發后,延遲執行,避免多次觸發。
- 節流(throttle):限制事件在一定時間內只觸發一次。
16. 什么是 Promise?
Promise是異步編程的一種解決方案,三種狀態:pending → fulfilled / rejected。
17. async/await 的原理?
async/await 是 Promise 的語法糖,await 會阻塞異步代碼的執行,直到 Promise 解決。
18. JavaScript 的事件循環機制?
- 宏任務:script、setTimeout、setInterval、I/O
- 微任務:Promise.then、MutationObserver、queueMicrotask執行順序:宏任務 → 微任務 → 渲染 → 宏任務 …
19. 什么是柯里化(currying)?
把一個多參函數轉換成一系列單參函數:
function add(a) {
return (b) => a + b;
}
add(2)(3); // 520. 什么是函數式編程?
強調函數的純粹性(無副作用)、組合、不可變性。
21. 箭頭函數和普通函數的區別?
- 沒有
this,從作用域繼承。 - 不能作為構造函數。
- 沒有
arguments。
22. 什么是解構賦值?
const [a, b] = [1, 2];
const {x, y} = {x:10, y:20};23. 什么是展開運算符?
const arr = [1,2];
const newArr = [...arr, 3];24. Set 和 Map 的區別?
Set:值唯一。Map:鍵值對,鍵可以是任意類型。
25. WeakMap 和 Map 的區別?
WeakMap鍵必須是對象。- 鍵是弱引用,垃圾回收不影響。
26. 什么是 Proxy?
Proxy 可以攔截對象的操作,比如 get、set,常用于數據綁定。
27. 什么是 Symbol?
唯一的標識符,避免屬性名沖突。
28. 什么是 BigInt?
用于表示超過 Number.MAX_SAFE_INTEGER 的整數。
29. 什么是模塊化(ES Modules)?
export導出,import導入。- 靜態加載,編譯時確定依賴。
30. import 和 require 的區別?
require是 CommonJS,同步執行。import是 ES6 模塊,靜態加載。
31. 如何實現數組去重?
[...new Set([1,1,2,3])]32. 如何實現深拷貝?
JSON.parse(JSON.stringify(obj));33. 如何判斷對象是否為空?
Object.keys(obj).length === 0;34.手寫防抖函數?
function debounce(fn, delay){
let timer;
return (...args)=>{
clearTimeout(timer);
timer=setTimeout(()=>fn(...args),delay);
}
}35. 手寫節流函數?
function throttle(fn, delay){
let last=0;
return (...args)=>{
let now=Date.now();
if(now-last>delay){
fn(...args);
last=now;
}
}
}36. 如何實現一個深比較?
遞歸比較對象的每個屬性。
37. 如何實現數組扁平化?
arr.flat(Infinity);38. 如何實現數組亂序?
arr.sort(()=>Math.random()-0.5);39. 如何實現 sleep?
const sleep = ms => new Promise(r=>setTimeout(r, ms));40. 如何實現千分位格式化?
"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, ",");41. JS 為什么是單線程的?
因為瀏覽器只有一個 UI 線程,避免多線程同時修改 DOM 造成混亂。
42. 什么是垃圾回收機制?
JS 采用 標記清除(Mark-Sweep) 算法,無法被引用的對象會被回收。
43. 什么是內存泄漏?
不再使用的對象仍然被引用,無法回收,比如:全局變量、閉包、未清理的定時器。
44. 解釋下 JSONP?
利用 <script> 標簽無跨域限制,請求數據并執行回調函數。
45. 什么是 CORS?
跨域資源共享,服務端通過響應頭 Access-Control-Allow-Origin 允許跨域請求。
46. 什么是同源策略?
協議、域名、端口都相同才算同源,否則限制跨域訪問。
47. 解釋下事件循環中的微任務和宏任務?
- 微任務:Promise.then
- 宏任務:setTimeout
- 執行順序:一個宏任務 → 所有微任務 → 渲染。
48. async/await 如何捕獲異常?
用 try/catch 包裹 await。
49. JS 中的 this 綁定規則?
- 默認綁定:全局
this → window。 - 隱式綁定:誰調用指向誰。
- 顯式綁定:
call/apply/bind。 - new 綁定:指向實例對象。
50. 什么是事件循環中的渲染機制?
瀏覽器會在 宏任務 → 微任務 → requestAnimationFrame → 渲染 的流程中刷新頁面。
寫在最后
JavaScript 的知識體系龐大,面試中??嫉牟粌H僅是語法本身,更是你對底層原理和應用場景的理解。
掌握這些高頻考點,能讓你在面試中更自信,但真正的核心競爭力,還在于把知識融會貫通,應用到實際項目中。
希望今天內容能幫助到你,最后感謝你的閱讀,祝編程愉快!





























