网站欣赏与创建网页教案,profile wordpress,网站重新备案需要多长时间,网站做md5脚本以下是前端面试中 JavaScript 基础易错问题的详解#xff0c;结合常见考点和易混淆概念进行解析#xff1a; ⚠️ 一、变量作用域与提升
var vs let/const
◦ 变量提升#xff1a;var 声明的变量会提升到作用域顶部#xff08;值为 undefined#xff09;#xff0c;而 …以下是前端面试中 JavaScript 基础易错问题的详解结合常见考点和易混淆概念进行解析 ⚠️ 一、变量作用域与提升
var vs let/const
◦ 变量提升var 声明的变量会提升到作用域顶部值为 undefined而 let/const 存在暂时性死区声明前访问报错。
◦ 循环陷阱
for (var i 0; i 3; i) { setTimeout(() console.log(i)); // 输出 3,3,3共享同一作用域 } for (let i 0; i 3; i) { setTimeout(() console.log(i)); // 输出 0,1,2块级作用域 }
解决使用 let 或 IIFE立即执行函数创建独立作用域。
全局变量污染
未使用声明关键字如 x 10会创建全局变量严格模式“use strict”可避免此问题。 二、异步与事件循环
setTimeout 延迟问题
◦ 即使延迟为 0回调仍会进入任务队列等待同步代码执行完毕。
◦ 循环中 var 声明的变量会在异步回调执行时变为最终值如循环结束后的 i。
事件队列示例
document.addEventListener(“click”, () console.log(“Click”)); // 异步事件 function sleep() { /* 同步阻塞 2 秒 */ } sleep(); // 阻塞期间点击不会触发事件直到同步代码完成3。 三、闭包与内存管理
闭包原理
函数保留其词法作用域的引用
function outer() { let count 0; return () count; // 闭包持有 count 的引用 } const counter outer(); counter(); // 1变量不会被回收6,7。
内存泄漏风险
◦ 闭包引用大对象时即使未使用也可能阻止垃圾回收
function createHandler() { const data new Array(1000000); return () console.log(data[0]); // data 被闭包持有 } // 解决不再需要时手动解除引用如 data null6,7。
◦ 循环中闭包共享变量需通过参数传递值非引用。 四、类型转换与比较 与
◦ 隐式类型转换规则
[] ![] // true: ![] → false → 0, [] → “” → 0 0 “0” // true: 字符串转数字 null undefined // true特殊规则1,4。
◦ 优先使用 避免意外转换。
typeof 与 null
typeof null “object”历史遗留 bug判断数组用 Array.isArray()。 五、this 绑定规则
this 由调用方式决定
const obj { name: “A”, log() { console.log(this.name); // “A”obj 调用 function inner() { console.log(this); // window默认绑定 } inner(); } }; obj.log();
• 解决箭头函数继承外层 this或使用 bind/call 显式绑定。 六、对象与引用
深浅拷贝
◦ 直接赋值是浅拷贝共享引用
let a [1, 2]; let b a; b.push(3); // a 也变为 [1,2,3]1,5。
◦ 深拷贝方法JSON.parse(JSON.stringify(obj))不支持函数或递归复制。
重复属性名
const obj { a: “one”, b: “two”, a: “three” }; console.log(obj); // {a: “three”, b: “two”}后声明的覆盖前者1。 ⚡ 七、其他易错点
浮点数精度
0.1 0.2 ! 0.3二进制浮点数问题需用 toFixed(2) 处理。
稀疏数组
const arr [1, , 3]; // 中间为空 arr.map(x x * 2); // [2, empty, 6]跳过空位4。
switch 严格比较
switch (new String(“A”)) { case “A”: console.log(“Case A”); // 不执行对象 vs 字符串 default: console.log(“Unknown”); // 输出此4。 } 总结
理解这些问题的核心在于
• 作用域块级 vs 函数级
• 异步机制事件队列、微任务/宏任务
• 引用类型对象、数组的共享特性
• 隐式转换规则避免用
面试时不仅要答对更要解释背后的原理如闭包的内存管理、this 的动态绑定展现深度思考能力。
—— 以下是前端面试中 JavaScript 基础易错问题的深度解析结合高频考点和开发者常见误区从原理到解决方案进行系统梳理 ⚠️ 一、作用域与变量声明
变量提升与暂时性死区
◦ var 声明的变量会提升至作用域顶部值为 undefined而 let/const 虽提升但存在暂时性死区声明前访问报错。
◦ 典型陷阱
for (var i 0; i 3; i) { setTimeout(() console.log(i)); // 输出 3 个 3共享同一作用域 } for (let i 0; i 3; i) { setTimeout(() console.log(i)); // 输出 0,1,2块级作用域隔离1 }
解决优先使用 let 或通过 IIFE 创建独立作用域。
全局变量污染
未声明直接赋值如 x 10会创建全局变量严格模式“use strict”可避免此问题。 二、闭包核心原理与陷阱
闭包的本质
内部函数持有外部函数作用域的引用即使外部函数已执行完毕
function createCounter() { let count 0; // 被闭包引用的变量 return () count; } const counter createCounter(); counter(); // 1count 未被回收6,7
循环中的闭包陷阱
for (var i 0; i 5; i) { setTimeout(() console.log(i)); // 输出 5 个 5 }
原因所有回调共享同一变量 i循环结束后 i 值为 5。
解决
◦ 使用 let 声明 i块级作用域
◦ 或通过 IIFE 捕获瞬时值
for (var i 0; i 5; i) { (function(j) { setTimeout(() console.log(j)); // 输出 0,1,2,3,4 })(i); }
内存泄漏风险
闭包引用大对象时可能阻止垃圾回收
function createHeavyClosure() { const bigData new Array(1000000); return () console.log(bigData[0]); } const leakyFunc createHeavyClosure(); // 不再需要时手动解除引用leakyFunc null6 ⏳ 三、异步与事件循环
setTimeout 的延迟问题
◦ 延迟参数为 0 仍属异步任务需等待同步代码执行完毕
setTimeout(() console.log(“Timeout”), 0); console.log(“Sync”); // 先输出 “Sync”再输出 “Timeout”
◦ 事件队列阻塞长时间同步任务如循环会延迟异步回调执行导致事件响应滞后。
Promise 错误处理遗漏
未捕获的 Promise 错误会触发 unhandledrejection 事件
fetch(url).then(res res.json()); // 缺少 .catch() // 正确做法 fetch(url) .then(res res.json()) .catch(err console.error(“请求失败:”, err)); // 显式捕获3 四、this 动态绑定
this 值由调用方式决定
const obj { name: “A”, log() { console.log(this.name); // “A”obj 调用 const inner () console.log(this.name); // “A”箭头函数继承外层 this inner(); } }; const fn obj.log; fn(); // undefined默认绑定到全局4,5
关键规则
• 普通函数调用this 指向全局对象非严格模式
• 方法调用this 指向调用对象
• 箭头函数继承定义时的外层 this
解决使用 bind 显式绑定或箭头函数。 五、类型转换与比较 的隐式转换陷阱
[] ![] // true![] → false → 0, [] → “” → 0 0 “0” // true字符串转数字 null undefined // true特殊规则3,5
建议始终使用 避免意外转换。
typeof 与 null 的遗留问题
typeof null “object”历史 Bug判断数组用 Array.isArray()。 ⚠️ 六、其他高频易错点
深浅拷贝混淆
◦ 直接赋值是浅拷贝共享引用
const a [1, 2]; const b a; b.push(3); // a 变为 [1,2,3]2,5
◦ 深拷贝方案JSON.parse(JSON.stringify(obj))忽略函数/Symbol或递归克隆。
浮点数精度问题
0.1 0.2 ! 0.3IEEE 754 双精度浮点限制需用 toFixed(2) 处理显示。
数组遍历的坑
for…in 会遍历原型链属性且不保证顺序应使用 for 循环或 forEach
Array.prototype.foo 1; const arr [2, 3]; for (let i in arr) console.log(i); // 输出 0, 1, “foo”污染 总结与应对策略
• 作用域与闭包理解词法作用域链避免循环引用泄漏及时解除引用
• 异步机制掌握事件循环宏任务/微任务Promise 错误必捕获
• 类型安全禁用 善用可选链?.与空值合并??
• 代码健壮性使用 ESLint 静态检查单元测试覆盖边界条件如 null、空数组
更多实战案例可参考闭包深度解析(http://www.ppmy.cn/news/1669535.html) | 异步错误处理指南(https://www.toutiao.com/article/7486748618485957171/) | this 绑定剖析(https://blog.csdn.net/weixin_42429220/article/details/136002209)