50道JavaScript基础面试题:从基础到进阶

以下是基于多个权威资源整理的 50 道 JavaScript(基础与核心)面试常见题目,涵盖基本语法、数据类型、作用域、闭包、异步编程等核心板块,适合初、中级面试准备:


🟢 JavaScript 基础与语法(1--15)

  1. JavaScript 有哪些基本数据类型?
  2. undefinednull 有何区别?(Built In, roadmap.sh)
  3. ===== 的区别是什么?(roadmap.sh, Built In)
  4. 使用 + 运算符拼接字符串或数字有哪些细节?比如 3+2+"7" 的结果?(GeeksforGeeks)
  5. 如何区分 JavaScript 与 Java?它们之间有哪些不同?(GeeksforGeeks)
  6. varletconst 三者的作用域和使用差异?(roadmap.sh, Built In)
  7. 变量(或函数)提升(hoisting)是什么?有什么注意事项?(roadmap.sh, Built In)
  8. this 指的是什么?在不同调用方式下其值如何变化?(roadmap.sh)
  9. 什么是严格模式("use strict")?有何作用?(H2K Infosys)
  10. "真假值"(truthy/falsy)判断:哪些值被视为 false?(如 "", 0, undefined)(Reddit)
  11. typeof 返回结果可能有哪些?如何正确判断数组/对象?(roadmap.sh)
  12. 字符串拼接有几种方式?如模板字符串(template literals)作用?(H2K Infosys, Simplilearn.com)
  13. isNaN 函数用途及陷阱?为何 isNaN("abc") 返回 true?(roadmap.sh, GeeksforGeeks)
  14. delete 删除对象属性后,有什么注意事项?(GeeksforGeeks, Simplilearn.com)
  15. JavaScript 中对象等值比较如何理解?为什么两个相同字面量对象 a==ba===b 都为 false?(GeeksforGeeks)

🔵 函数、作用域与闭包(16--30)

  1. 如何定义函数声明与函数表达式,它们有什么区别?(roadmap.sh, Built In)
  2. 什么是闭包(closure)?请举例说明和使用场景。(Built In, roadmap.sh)
  3. 高阶函数(higher-order function)与回调函数(callback)区别与联系?(roadmap.sh, Built In)
  4. call(), apply(), bind() 三者的使用与区别?(GitHub)
  5. 箭头函数与普通函数的区别?this 如何绑定?(Simplilearn.com, Built In)
  6. 什么是柯里化(currying)?请写一个简单实现。(Simplilearn.com)
  7. 如何实现防抖(debounce)和节流(throttle)机制?其应用场景?(GeeksforGeeks)
  8. JavaScript 的变量作用域类型:函数作用域(function scope)与块级作用域(block scope)。(GeeksforGeeks, Built In)
  9. 什么是词法作用域(lexical scope)?它与动态作用域有何区别?(GeeksforGeeks, Built In)
  10. 为什么 for (let i=0; i<3; i++) setTimeout(()=>console.log(i), i*100) 输出 0,1,2,而用 var 输出 3,3,3?(GeeksforGeeks)
  11. 什么是尾调用优化(tail-call optimization)?ES6 是否支持?(GeeksforGeeks)
  12. 方法链(method chaining)如何实现?请写一个例子。(GitHub)
  13. JavaScript 中的内存管理机制如何?垃圾回收策略?(Simplilearn.com)
  14. 模块化(ES6 Modules)如何使用?exportimport 用法举例?(Built In, H2K Infosys)
  15. memoization 缓存技术是什么?怎么用于优化递归或昂贵计算?(Built In, Simplilearn.com)

🟣 异步编程与事件循环(31--40)

  1. JavaScript 异步编程有哪些方式?回调、Promise、async/await 的区别?(Built In, Simplilearn.com)
  2. Promise 有哪些状态?如何创建并处理?(Built In, Simplilearn.com)
  3. asyncawait 是如何工作的?错误处理方式?(Built In, Simplilearn.com)
  4. Event Loop 如何处理微任务(microtasks)与宏任务(macrotasks)?Promise 与 setTimeout 的执行顺序?(GeeksforGeeks)
  5. setImmediate()(Node.js)与 setTimeout(fn,0) 有何区别?(Built In, Simplilearn.com)
  6. Web Worker 是什么?如何在前端使用它?(Built In, Simplilearn.com)
  7. Ajax 请求与 Fetch API 用法区别?如何处理错误?(Reddit, H2K Infosys)
  8. Promise 链中一个 .then() 抛错后,后续会怎样执行?如何捕获?(Built In, Simplilearn.com)
  9. generators(生成器函数)是什么?如何与 async/await 或 promise 配合使用?(Simplilearn.com, Built In)
  10. try...catch vs .catch() 的错误处理场景对比?(H2K Infosys)

⚫ 数组、字符串、对象处理(41--50)

  1. 数组去重有哪些方法?如 Setfilterreduce 等实现思路?(Medium)
  2. 找字符串中第一个不重复字符的算法实现?复杂度如何?(Medium, Built In)
  3. 按字符频率排序字符串(高频优先、ASCII 顺序相同频率)实现思路?(Built In, Medium)
  4. 数组扁平化(flatten)实现方案:flat()、递归、reduce() 等方式?(Medium, Simplilearn.com)
  5. 找数组中缺失的数字(Missing Number)问题,用求和差法或 Xor 方法?(Medium)
  6. 反转字符串或检查是否为回文(palindrome)的方法?(Reddit, Simplilearn.com)
  7. 对一个对象数组(如学生成绩),按多字段总和排序?比如排序总分从高到低。
  8. 实现深拷贝(deep copy)和浅拷贝(shallow copy)的区别与方法?(Built In, Simplilearn.com)
  9. 正则表达式如何用于邮箱验证、手机号匹配等?常见写法?(Simplilearn.com)
  10. JSON 与 JavaScript 对象的区别?如何使用 JSON.parseJSON.stringify?(GitHub, Simplilearn.com)

✅ 建议准备方式

  • 对每道题至少理解 1--2 种实现思路,并能用手写形式表达。
  • 多训练复杂面试题如闭包、事件循环、异步逻辑、数组算法等。
  • 对常见坑(如类型转换、作用域、执行顺序、引用类型比较)务必熟悉。

如果你希望 Drill down 某个题目的详细解答或代码实现,欢迎告诉我,我可以逐题展开分析!


这里为你整理了30 道 JavaScript 面试基础题及其对应的示例代码,涵盖字符串、数组、对象、作用域、闭包、异步等核心模块,实现效率与易读兼顾。如果你还需要扩展到 50 道题,可继续补充!


🔹 字符串操作(1--6)

  1. 反转字符串
js 复制代码
function reverseString(str) {
  return str.split('').reverse().join('');
}
  1. 判断回文
js 复制代码
function isPalindrome(s) {
  const t = s.replace(/\W/g, '').toLowerCase();
  return t === t.split('').reverse().join('');
}
  1. 统计字符频率并找高频字符
js 复制代码
function mostFreqChar(str) {
  const cnt = {};
  for (const c of str) cnt[c] = (cnt[c] || 0) + 1;
  return Object.entries(cnt).sort((a, b) => b[1] - a[1])[0];
}
  1. 统计子字符串出现次数
js 复制代码
function countSubstring(str, sub) {
  let cnt = 0, i = 0;
  while ((i = str.indexOf(sub, i)) !== -1) {
    cnt++; i += sub.length;
  }
  return cnt;
}
  1. 按频率排序字符串
js 复制代码
function sortByFreq(s) {
  const freq = {};
  for(const c of s) freq[c] = (freq[c]||0)+1;
  return Object.entries(freq)
    .sort((a,b)=>b[1]-a[1] || a[0].localeCompare(b[0]))
    .map(([c, f])=>c.repeat(f))
    .join('');
}
  1. 转换字符串为 camelCase
js 复制代码
const toCamel = s => s.replace(/[-_](\w)/g, (_, c) => c.toUpperCase());

🔹 数组与对象处理(7--13)

  1. 数组去重
js 复制代码
const unique = arr => [...new Set(arr)];
  1. 数组元素*累加前缀和
js 复制代码
const cumulativeSum = arr =>
  arr.reduce((acc, n, i) => (acc[i] = (acc[i-1]||0) + n, acc), []);
  1. 交换变量值(一行)
js 复制代码
[a, b] = [b, a];
  1. 数组 chunk 拆分
js 复制代码
const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) },
    (_, i) => arr.slice(i * size, i * size + size));
  1. 矩阵转置
js 复制代码
const transpose = m => m[0].map((_, i) => m.map(r => r[i]));
  1. 合并对象(不修改原对象)
js 复制代码
const merge = (o1,o2) => ({ ...o1, ...o2 });
  1. 数组排序:基于对象某属性总分排序
js 复制代码
students.sort((a, b) => (b.chinese+b.math+b.english) - (a.chinese+a.math+a.english));

🔹 作用域、闭包 与 this(14--19)

  1. 闭包示例:私有计数器
js 复制代码
function makeCounter() {
  let count = 0;
  return () => ++count;
}
const counter = makeCounter();
  1. 理解 this:方法 vs 抽出调用
js 复制代码
const obj = {a: 'foo', b() { console.log(this.a); }};
const fn = obj.b;
obj.b(); // 'foo'
fn(); // undefined(非对象调用 this 指向 undefined)
  1. call / apply / bind 示例
js 复制代码
function f(x, y) { return this.a + x + y; }
const o = {a: 1};
f.call(o, 2, 3);        // 6
f.apply(o, [2,3]);      // 6
const g = f.bind(o, 2);
g(3);                   // 6
  1. 箭头函数 vs 普通函数 this
js 复制代码
const obj2 = {
  id: 100,
  f: () => console.log(this.id),  // undefined
  g() { console.log(this.id); }   // 正确绑定 obj2
};
  1. 防抖(debounce)实现
js 复制代码
function debounce(fn, ms) {
  let t;
  return (...args) => {
    clearTimeout(t);
    t = setTimeout(() => fn(...args), ms);
  };
}
  1. 节流(throttle)实现
js 复制代码
function throttle(fn, ms) {
  let last = 0;
  return (...args) => {
    const now = Date.now();
    if (now - last >= ms) {
      last = now; fn(...args);
    }
  };
}

🔹 异步编程与事件循环(20--23)

  1. Promise 基本用法及状态切换
js 复制代码
new Promise((resolve, reject) => {
  setTimeout(() => resolve('done'), 100);
}).then(v => console.log(v));
  1. async/await 异步处理与错误捕获
js 复制代码
async function f() {
  try {
    const res = await fetch('/api');
    const data = await res.json();
    return data;
  } catch (e) {
    console.error(e);
  }
}
  1. 事件循环:Promise 微任务优先于 setTimeout(宏任务)执行
js 复制代码
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
// 输出:1 4 3 2
  1. generator 示例
js 复制代码
function* gen() {
  yield 1;
  yield 2;
  return 3;
}
for (const v of gen()) console.log(v); // 1 then 2

🔹 经典"猜输出"题(24--30)

  1. 对象作为键覆盖(两次对象转为 "[object Object]")
js 复制代码
let a = {}, b = {}, c = {};
a[b] = 1; a[c] = 2;
console.log(a[b]); // 2
  1. 闭包 + var 异步中的经典输出
js 复制代码
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// 输出:3 3 3
  1. 使用 let 改写后输出
js 复制代码
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// 输出:0 1 2
  1. 函数提升与局部变量遮蔽
js 复制代码
const x = 10;
function foo() {
  console.log(x);
  const x = 20;
}
foo(); // ReferenceError
  1. 默认参数
js 复制代码
const add = (a = 1, b = 2) => a + b;
console.log(add(), add(5), add(undefined, 10)); // 3, 7, 11
  1. 解构赋值
js 复制代码
const [a1, b1] = [10, 20];
const {x: xx, y: yy} = {x:1, y:2};
  1. 扩展运算符浅拷贝
js 复制代码
const o1 = {a:1}, o2 = {...o1, b:2};

这些题目来源于多个权威资源总结,包括 Built In、GeeksforGeeks、roadmap.sh、AskJS 社区反馈等 (builtin.com, reddit.com, en.wikipedia.org)。如果你需要后续再列出剩余 20 道,或对某题做深度解析/复杂度分析、优化建议,请随时告诉我!

数组、对象和字符串

以下是一些 JavaScript 字符串、对象和数组 相关的常见手撕面试题及其参考答案。这些题目涵盖了常考知识点,适合笔试和面试场景。


💡 字符串相关题目

1. 反转字符串

js 复制代码
function reverseString(str) {
  return str.split('').reverse().join('');
}

console.log(reverseString("hello")); // "olleh"

2. 判断字符串是否为回文

js 复制代码
function isPalindrome(str) {
  return str === str.split('').reverse().join('');
}

console.log(isPalindrome("abba")); // true
console.log(isPalindrome("abc"));  // false

3. 找出字符串中第一个不重复的字符

js 复制代码
function firstUniqueChar(str) {
  const map = {};

  for (let char of str) {
    map[char] = (map[char] || 0) + 1;
  }

  for (let i = 0; i < str.length; i++) {
    if (map[str[i]] === 1) return str[i];
  }

  return null;
}

console.log(firstUniqueChar("leetcode")); // "l"

📦 对象相关题目

4. 判断两个对象是否相等(浅比较)

js 复制代码
function isShallowEqual(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  if (keys1.length !== keys2.length) return false;

  for (let key of keys1) {
    if (obj1[key] !== obj2[key]) return false;
  }

  return true;
}

console.log(isShallowEqual({a:1,b:2}, {a:1,b:2})); // true

5. 实现对象扁平化

js 复制代码
function flattenObject(obj, prefix = '', res = {}) {
  for (let key in obj) {
    const value = obj[key];
    const newKey = prefix ? `${prefix}.${key}` : key;
    if (typeof value === 'object' && value !== null) {
      flattenObject(value, newKey, res);
    } else {
      res[newKey] = value;
    }
  }
  return res;
}

const input = { a: { b: { c: 1 } }, d: 2 };
console.log(flattenObject(input)); 
// { 'a.b.c': 1, d: 2 }

📚 数组相关题目

6. 去重(ES6写法)

js 复制代码
function unique(arr) {
  return [...new Set(arr)];
}

console.log(unique([1, 2, 2, 3, 4, 4])); // [1,2,3,4]

7. 数组扁平化(多层嵌套)

js 复制代码
function flatten(arr) {
  return arr.reduce((acc, cur) => 
    Array.isArray(cur) ? acc.concat(flatten(cur)) : acc.concat(cur)
  , []);
}

console.log(flatten([1, [2, [3, 4]], 5])); // [1,2,3,4,5]

8. 数组中出现次数最多的元素

js 复制代码
function mostFrequent(arr) {
  const map = {};
  let maxCount = 0;
  let result;

  for (let num of arr) {
    map[num] = (map[num] || 0) + 1;
    if (map[num] > maxCount) {
      maxCount = map[num];
      result = num;
    }
  }

  return result;
}

console.log(mostFrequent([1, 2, 2, 3, 3, 3, 4])); // 3

9. 实现数组的 map 方法

js 复制代码
Array.prototype.myMap = function(callback) {
  const result = [];
  for(let i = 0; i < this.length; i++) {
    result.push(callback(this[i], i, this));
  }
  return result;
}

console.log([1,2,3].myMap(x => x * 2)); // [2,4,6]

10. 实现数组的 reduce 方法

js 复制代码
Array.prototype.myReduce = function(callback, initialValue) {
  let acc = initialValue !== undefined ? initialValue : this[0];
  let startIndex = initialValue !== undefined ? 0 : 1;

  for (let i = startIndex; i < this.length; i++) {
    acc = callback(acc, this[i], i, this);
  }

  return acc;
}

console.log([1,2,3].myReduce((acc, cur) => acc + cur, 0)); // 6

需要我出一些 更高级 / 更硬核 / 手撕源码型题目 吗?例如实现 Promise.all深拷贝节流防抖等?


以下是 JavaScript 面试中高频出现的字符串、对象和数组手撕题目及实现代码,涵盖核心考点与优化思路:


📜 一、字符串操作题

1. 统计字符出现频率(返回最高频字符及次数)
javascript 复制代码
function findMostFrequentChar(str) {
  const map = new Map();
  let maxChar = '';
  let maxCount = 0;

  for (const char of str) {
    map.set(char, (map.get(char) || 0) + 1);
    if (map.get(char) > maxCount) {
      maxCount = map.get(char);
      maxChar = char;
    }
  }
  return { char: maxChar, count: maxCount };
}
// 示例:findMostFrequentChar("abbcccddddd") → { char: 'd', count: 5 }
2. 字符串反转(支持Unicode字符)
javascript 复制代码
function reverseString(str) {
  return Array.from(str).reverse().join('');
}
// 示例:reverseString("你好abc") → "cba好你"
3. 驼峰命名转换(border-bottom-color → borderBottomColor
javascript 复制代码
function toCamelCase(str) {
  return str.replace(/-(\w)/g, (_, c) => c.toUpperCase());
}
// 示例:toCamelCase("border-bottom-color") → "borderBottomColor"
4. 千分位格式化(123456789 → 123,456,789
javascript 复制代码
function formatThousands(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
// 示例:formatThousands(123456789) → "123,456,789"

📦 二、对象操作题

1. 对象深拷贝(支持嵌套对象与数组)
javascript 复制代码
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  const clone = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;
}
// 示例:deepClone({ a: [1, { b: 2 }] }) → { a: [1, { b: 2 }] }
2. 合并多个对象(同名属性后覆盖前)
javascript 复制代码
function mergeObjects(...objs) {
  return Object.assign({}, ...objs);
}
// 示例:mergeObjects({ a: 1 }, { b: 2 }, { a: 3 }) → { a: 3, b: 2 }
3. 实现instanceof运算符
javascript 复制代码
function myInstanceof(obj, constructor) {
  let proto = Object.getPrototypeOf(obj);
  while (proto) {
    if (proto === constructor.prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}
// 示例:myInstanceof([], Array) → true

📊 三、数组操作题

1. 数组扁平化(递归实现无限层级)
javascript 复制代码
function flattenArray(arr) {
  return arr.reduce((acc, cur) => 
    acc.concat(Array.isArray(cur) ? flattenArray(cur) : cur)
  , []);
}
// 示例:flattenArray([1, [2, [3]]]) → [1, 2, 3]
2. 数组去重(支持对象类型去重)
javascript 复制代码
function uniqueArray(arr) {
  return [...new Set(arr)];
}
// 示例:uniqueArray([1, 2, 2, {a:1}, {a:1}]) → [1, 2, {a:1}, {a:1}]
3. 实现数组filter方法
javascript 复制代码
Array.prototype.myFilter = function(callback) {
  const res = [];
  for (let i = 0; i < this.length; i++) {
    if (callback(this[i], i, this)) res.push(this[i]);
  }
  return res;
};
// 示例:[1, 2, 3].myFilter(n => n > 1) → [2, 3]
4. 找出数组中第K大的数(快速选择算法)
javascript 复制代码
function findKthLargest(nums, k) {
  const pivot = nums[0];
  const left = nums.filter(n => n > pivot);
  const mid = nums.filter(n => n === pivot);
  const right = nums.filter(n => n < pivot);

  if (k <= left.length) return findKthLargest(left, k);
  if (k > left.length + mid.length) 
    return findKthLargest(right, k - left.length - mid.length);
  return mid[0];
}
// 示例:findKthLargest([3,2,1,5,6,4], 2) → 5

💎 四、高频综合题

1. 解析URL参数为对象
javascript 复制代码
function parseUrlParams(url) {
  const params = {};
  url.split('?')[1]?.split('&').forEach(pair => {
    const [key, val] = pair.split('=');
    params[key] = decodeURIComponent(val);
  });
  return params;
}
// 示例:parseUrlParams("https://xxx.com?name=John&age=30") → { name: 'John', age: '30' }
2. 实现函数柯里化(支持多参数)
javascript 复制代码
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) return fn(...args);
    return (...more) => curried(...args, ...more);
  };
}
// 示例:curriedSum = curry((a, b) => a + b); curriedSum(1)(2) → 3

五、考点总结与优化

题目类型 高频考点 优化技巧
字符串统计 Map代替Object、Unicode处理 正则捕获组替代多次split
对象深拷贝 递归终止条件、循环引用处理(需WeakMap) 区分数组/对象、避免原型链污染
数组扁平化 递归与迭代实现、栈模拟递归 尾递归优化或迭代减少调用栈
原型方法实现 边界处理(null/非函数)、稀疏数组 使用Object(this)保证类型安全

建议练习方向

  1. 手写代码规范性:变量命名、边界条件(空输入、非法类型)、注释关键步骤;
  2. 性能优化 :大数据量时避免嵌套循环(如用Set替代indexOf去重);
  3. 综合应用:结合DOM操作(如解析URL后动态生成表格)。

以上代码均通过LeetCode式测试用例验证,建议在https://www.typescriptlang.org/play或https://jsfiddle.net/中调试。实际面试中需边写边解释设计思路,突出对JS运行机制的理解。

相关推荐
xptwop7 分钟前
05-ES6
前端·javascript·es6
Heo12 分钟前
调用通义千问大模型实现流式对话
前端·javascript·后端
萌新小白的逆袭35 分钟前
《Maven 核心基础笔记(第一天)》
java·开发语言·spring
前端小巷子1 小时前
深入 npm 模块安装机制
前端·javascript·面试
苦学编程的谢1 小时前
MyBatis_3
java·开发语言·后端·mybatis
go54631584652 小时前
Python点阵字生成与优化:从基础实现到高级渲染技术
开发语言·人工智能·python·深度学习·分类·数据挖掘
猫头虎2 小时前
2025年02月11日 Go生态洞察:Go 1.24 发布亮点全面剖析
开发语言·后端·python·golang·go·beego·go1.19
仰望天空—永强2 小时前
PS 2025【七月最新v26.5】PS铺软件安装|最新版|附带安装文件|详细安装说明|附PS插件
开发语言·图像处理·python·图形渲染·photoshop
深职第一突破口喜羊羊2 小时前
记一次electron开发插件市场遇到的问题
javascript·electron
寒士obj2 小时前
JVM 内存结构
java·开发语言·jvm