JavaScript 面試中算法題側重語言特性(閉包、原型、事件循環)與內置 API 靈活運用。本文精選 20 道高頻題,涵蓋基礎語法陷阱、數組/字符串操作、數據結構實現、經典演算法,附 ES6+ 現代寫法與複雜度分析。
console.log(x); // undefined (非 ReferenceError)
var x = 5;
// 等價於:
var x;
console.log(x);
x = 5;
重點:var 聲明提升,賦值不提升;let/const 有暫時性死區 (TDZ)。
"use strict";
x = 3.14; // ReferenceError: x is not defined
// 未聲明變量賦值直接報錯,避免隱式全局污染
child.addEventListener('click', e => {
e.stopPropagation(); // 標準
// e.cancelBubble = true; // IE9-
}, false);
0 == false // true (類型轉換)
0 === false // false (嚴格相等:類型+值)
'2' == 2 // true
'2' === 2 // false
建議:始終用 ===,避免隱式轉換陷阱。
null:人為賦值的「空對象指針」,typeof null === 'object'。undefined:聲明未賦值、對象屬性不存在、函數無返回值。function maxProductOfThree(arr) {
arr.sort((a,b) => a - b);
const n = arr.length;
// 最大三正數 或 兩最小負數 * 最大正數
return Math.max(
arr[n-1] * arr[n-2] * arr[n-3],
arr[0] * arr[1] * arr[n-1]
);
}
// 測試:[-10, 7, 29, 30, 5, -10, -70] → 21000 (-70 * -10 * 30)
O(n log n) 排序法;O(n) 單掃描維護前三大/前二小亦可。
function findMissing(arr, min, max) {
const sum = arr.reduce((a,b) => a+b, 0);
const expected = (max * (max+1) - (min-1) * min) / 2;
return expected - sum;
}
// [2,5,1,4,9,6,3,7], 1, 9 → 8
// ES6 Set (最簡)
[...new Set([1,2,3,5,1,5,9,1,2,8])] // [1,2,3,5,9,8]
// Map/Object 手寫 (面試常考)
function unique(arr) {
const seen = {}, res = [];
for (const v of arr) if (!seen[v]) { seen[v]=1; res.push(v); }
return res;
}
function maxDiff(arr) {
if (arr.length < 2) return -1;
let min = arr[0], maxDiff = 0;
for (let i=1; i maxDiff) maxDiff = arr[i] - min;
if (arr[i] < min) min = arr[i];
}
return maxDiff > 0 ? maxDiff : -1;
}
// [7,8,4,9,9,15,3,1,10] → 11 (15-4),非 14 (15-1 因 1 在 15 後)
function productExceptSelf(nums) {
const n = nums.length, out = new Array(n);
let left = 1;
for (let i=0; i=0; i--) { out[i] *= right; right *= nums[i]; }
return out;
}
// [2,2,4,1] → [8,8,4,16]
function intersection(a, b) {
const set = new Set(a);
return [...new Set(b.filter(x => set.has(x)))];
}
// [2,2,4,1] & [1,2,0,2] → [2,1]
function reverseWords(str) {
return str.split(' ').map(w => w.split('').reverse().join('')).join(' ');
}
// "Welcome to JS" → "emocleW ot SJ"
function isAnagram(a, b) {
return a.toLowerCase().split('').sort().join('') ===
b.toLowerCase().split('').sort().join('');
}
// "Mary" & "Army" → true
function isPalindrome(s) {
const clean = s.toLowerCase().replace(/\s/g, '');
return clean === clean.split('').reverse().join('');
}
// "race car" → true
const inStack = [], outStack = [];
function enqueue(x) { inStack.push(x); }
function dequeue() {
if (!outStack.length) while (inStack.length) outStack.push(inStack.pop());
return outStack.pop();
}
function isBalanced(str) {
const stack = [];
for (const ch of str) {
if (ch === '{') stack.push(ch);
else if (ch === '}') { if (!stack.pop()) return false; }
}
return !stack.length;
}
// "{{}}{}" → true, "{}{{" → false
function toBinary(n) {
if (n < 1) return '';
return toBinary(Math.floor(n/2)) + (n % 2);
}
// 3 → "11", 8 → "1000"
function binarySearch(arr, target, l=0, r=arr.length-1) {
if (l > r) return -1;
const m = (l+r) >> 1;
if (arr[m] === target) return m;
return arr[m] > target ? binarySearch(arr, target, l, m-1)
: binarySearch(arr, target, m+1, r);
}
function isPowerOfTwo(n) {
return n > 0 && (n & (n-1)) === 0;
}
// 位運算:2的冪次二進制僅一個1,n&(n-1) 消除最低位1
Set/Map、解構、箭頭函數、展開運算符。Promise/async-await/setTimeout 順序。var。