当前位置: 首页 > news >正文

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. 反转字符串
function reverseString(str) {return str.split('').reverse().join('');
}
  1. 判断回文
function isPalindrome(s) {const t = s.replace(/\W/g, '').toLowerCase();return t === t.split('').reverse().join('');
}
  1. 统计字符频率并找高频字符
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. 统计子字符串出现次数
function countSubstring(str, sub) {let cnt = 0, i = 0;while ((i = str.indexOf(sub, i)) !== -1) {cnt++; i += sub.length;}return cnt;
}
  1. 按频率排序字符串
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
const toCamel = s => s.replace(/[-_](\w)/g, (_, c) => c.toUpperCase());

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

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

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

  1. 闭包示例:私有计数器
function makeCounter() {let count = 0;return () => ++count;
}
const counter = makeCounter();
  1. 理解 this:方法 vs 抽出调用
const obj = {a: 'foo', b() { console.log(this.a); }};
const fn = obj.b;
obj.b(); // 'foo'
fn(); // undefined(非对象调用 this 指向 undefined)
  1. call / apply / bind 示例
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
const obj2 = {id: 100,f: () => console.log(this.id),  // undefinedg() { console.log(this.id); }   // 正确绑定 obj2
};
  1. 防抖(debounce)实现
function debounce(fn, ms) {let t;return (...args) => {clearTimeout(t);t = setTimeout(() => fn(...args), ms);};
}
  1. 节流(throttle)实现
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 基本用法及状态切换
new Promise((resolve, reject) => {setTimeout(() => resolve('done'), 100);
}).then(v => console.log(v));
  1. async/await 异步处理与错误捕获
async function f() {try {const res = await fetch('/api');const data = await res.json();return data;} catch (e) {console.error(e);}
}
  1. 事件循环:Promise 微任务优先于 setTimeout(宏任务)执行
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
// 输出:1 4 3 2
  1. generator 示例
function* gen() {yield 1;yield 2;return 3;
}
for (const v of gen()) console.log(v); // 1 then 2

🔹 经典“猜输出”题(24–30)

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

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

数组、对象和字符串

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


💡 字符串相关题目

1. 反转字符串

function reverseString(str) {return str.split('').reverse().join('');
}console.log(reverseString("hello")); // "olleh"

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

function isPalindrome(str) {return str === str.split('').reverse().join('');
}console.log(isPalindrome("abba")); // true
console.log(isPalindrome("abc"));  // false

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

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. 判断两个对象是否相等(浅比较)

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. 实现对象扁平化

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写法)

function unique(arr) {return [...new Set(arr)];
}console.log(unique([1, 2, 2, 3, 4, 4])); // [1,2,3,4]

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

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. 数组中出现次数最多的元素

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 方法

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 方法

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. 统计字符出现频率(返回最高频字符及次数)
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字符)
function reverseString(str) {return Array.from(str).reverse().join('');
}
// 示例:reverseString("你好abc") → "cba好你"
3. 驼峰命名转换(border-bottom-color → borderBottomColor
function toCamelCase(str) {return str.replace(/-(\w)/g, (_, c) => c.toUpperCase());
}
// 示例:toCamelCase("border-bottom-color") → "borderBottomColor"
4. 千分位格式化(123456789 → 123,456,789
function formatThousands(num) {return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
// 示例:formatThousands(123456789) → "123,456,789"

📦 二、对象操作题

1. 对象深拷贝(支持嵌套对象与数组)
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. 合并多个对象(同名属性后覆盖前)
function mergeObjects(...objs) {return Object.assign({}, ...objs);
}
// 示例:mergeObjects({ a: 1 }, { b: 2 }, { a: 3 }) → { a: 3, b: 2 }
3. 实现instanceof运算符
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. 数组扁平化(递归实现无限层级)
function flattenArray(arr) {return arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flattenArray(cur) : cur), []);
}
// 示例:flattenArray([1, [2, [3]]]) → [1, 2, 3]
2. 数组去重(支持对象类型去重)
function uniqueArray(arr) {return [...new Set(arr)];
}
// 示例:uniqueArray([1, 2, 2, {a:1}, {a:1}]) → [1, 2, {a:1}, {a:1}]
3. 实现数组filter方法
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大的数(快速选择算法)
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参数为对象
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. 实现函数柯里化(支持多参数)
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运行机制的理解。

http://www.lryc.cn/news/600470.html

相关文章:

  • haproxy原理及实战部署
  • 根本是什么
  • 统计学07:概率论基础
  • Chukonu 阅读笔记
  • 分类预测 | MATLAB实现DBO-SVM蜣螂算法优化支持向量机分类预测
  • 深入解析YARN中的FairScheduler与CapacityScheduler:资源分配策略的核心区别
  • 检索召回率优化探究一:基于 LangChain 0.3集成 Milvus 2.5向量数据库构建的智能问答系统
  • 微信小程序 自定义带图片弹窗
  • 数据存储:OLAP vs OLTP
  • Flutter实现Retrofit风格的网络请求封装
  • Apache Doris Data Agent 解决方案:开启智能运维与数据治理新纪元
  • RS485转Profinet网关配置指南:高效启动JRT激光测距传感器测量模式
  • React入门学习——指北指南(第四节)
  • SQL Developer Data Modeler:一款免费跨平台的数据库建模工具
  • Flutter 提取图像主色调 ColorScheme.fromImageProvider
  • Javaweb————HTTP消息体拆分讲解
  • 渗透艺术系列之Laravel框架(一)
  • 互联网应用主流框架整合 Spring Boot开发
  • 大模型——字节Coze重磅开源!Dify何去何从
  • 车载诊断刷写 --- Flash关于擦除和写入大小
  • 解决VSCode中Github Copilot无法登陆的问题
  • AI Agent开发学习系列 - LangGraph(1): 用LangGraph创建我们的第一个Agent
  • 强化学习(第三课第三周)
  • 在一个存在的包里面编写msg消息文件
  • (二)使用 LangChain 从零开始构建 RAG 系统 RAG From Scratch
  • Ubuntu22.04提示找不到python命令的解决方案
  • [Linux入门] 初学者入门:Linux DNS 域名解析服务详解
  • STM32 FreeRTOS基础
  • 垃圾回收算法与垃圾收集器
  • cacti的命令执行和回显