Javascript基础内容回顾—变量提升、事件循环和闭包等内容

以下是前端面试中 JavaScript 基础易错问题的详解,结合常见考点和易混淆概念进行解析:


⚠️ 一、变量作用域与提升

  1. 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(立即执行函数)创建独立作用域。

  1. 全局变量污染

未使用声明关键字(如 x = 10)会创建全局变量,严格模式(“use strict”)可避免此问题。


🔄 二、异步与事件循环

  1. setTimeout 延迟问题

◦ 即使延迟为 0,回调仍会进入任务队列,等待同步代码执行完毕。

◦ 循环中 var 声明的变量会在异步回调执行时变为最终值(如循环结束后的 i)。

  1. 事件队列示例

document.addEventListener(“click”, () => console.log(“Click”)); // 异步事件
function sleep() { /* 同步阻塞 2 秒 */ }
sleep(); // 阻塞期间点击不会触发事件,直到同步代码完成3。


🔗 三、闭包与内存管理

  1. 闭包原理

函数保留其词法作用域的引用:

function outer() {
let count = 0;
return () => count++; // 闭包持有 count 的引用
}
const counter = outer();
counter(); // 1(变量不会被回收)6,7。

  1. 内存泄漏风险

◦ 闭包引用大对象时,即使未使用也可能阻止垃圾回收:

function createHandler() {
const data = new Array(1000000);
return () => console.log(data[0]); // data 被闭包持有
}
// 解决:不再需要时手动解除引用(如 data = null)6,7。

◦ 循环中闭包共享变量需通过参数传递值(非引用)。


🔍 四、类型转换与比较

  1. == 与 ===

◦ == 隐式类型转换规则:

[] == ![] // true: ![] → false → 0, [] → “” → 0
0 == “0” // true: 字符串转数字
null == undefined // true(特殊规则)1,4。

◦ 优先使用 === 避免意外转换。

  1. 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 显式绑定。


📦 六、对象与引用

  1. 深浅拷贝

◦ 直接赋值是浅拷贝(共享引用):

let a = [1, 2];
let b = a;
b.push(3); // a 也变为 [1,2,3]1,5。

◦ 深拷贝方法:JSON.parse(JSON.stringify(obj))(不支持函数)或递归复制。

  1. 重复属性名

const obj = { a: “one”, b: “two”, a: “three” };
console.log(obj); // {a: “three”, b: “two”}(后声明的覆盖前者)1。


⚡ 七、其他易错点

  1. 浮点数精度

0.1 + 0.2 !== 0.3(二进制浮点数问题),需用 toFixed(2) 处理。

  1. 稀疏数组

const arr = [1, , 3]; // 中间为空
arr.map(x => x * 2); // [2, empty, 6](跳过空位)4。

  1. switch 严格比较

switch (new String(“A”)) {
case “A”: console.log(“Case A”); // 不执行(对象 vs 字符串)
default: console.log(“Unknown”); // 输出此4。
}


💎 总结

理解这些问题的核心在于:

• 作用域(块级 vs 函数级)

• 异步机制(事件队列、微任务/宏任务)

• 引用类型(对象、数组的共享特性)

• 隐式转换规则(避免用 ==)

面试时不仅要答对,更要解释背后的原理(如闭包的内存管理、this 的动态绑定),展现深度思考能力。

——
以下是前端面试中 JavaScript 基础易错问题的深度解析,结合高频考点和开发者常见误区,从原理到解决方案进行系统梳理:


⚠️ 一、作用域与变量声明

  1. 变量提升与暂时性死区

◦ 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 创建独立作用域。

  1. 全局变量污染

未声明直接赋值(如 x = 10)会创建全局变量,严格模式(“use strict”)可避免此问题。


🔄 二、闭包核心原理与陷阱

  1. 闭包的本质

内部函数持有外部函数作用域的引用,即使外部函数已执行完毕:

function createCounter() {
let count = 0; // 被闭包引用的变量
return () => count++;
}
const counter = createCounter();
counter(); // 1(count 未被回收)6,7

  1. 循环中的闭包陷阱

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);
}

  1. 内存泄漏风险

闭包引用大对象时可能阻止垃圾回收:

function createHeavyClosure() {
const bigData = new Array(1000000);
return () => console.log(bigData[0]);
}
const leakyFunc = createHeavyClosure();
// 不再需要时手动解除引用:leakyFunc = null6


⏳ 三、异步与事件循环

  1. setTimeout 的延迟问题

◦ 延迟参数为 0 仍属异步任务,需等待同步代码执行完毕:

setTimeout(() => console.log(“Timeout”), 0);
console.log(“Sync”); // 先输出 “Sync”,再输出 “Timeout”

◦ 事件队列阻塞:长时间同步任务(如循环)会延迟异步回调执行,导致事件响应滞后。

  1. 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 显式绑定或箭头函数。


🔄 五、类型转换与比较

  1. == 的隐式转换陷阱

[] == ![] // true(![] → false → 0, [] → “” → 0)
0 == “0” // true(字符串转数字)
null == undefined // true(特殊规则)3,5

建议:始终使用 === 避免意外转换。

  1. typeof 与 null 的遗留问题

typeof null === “object”(历史 Bug),判断数组用 Array.isArray()。


⚠️ 六、其他高频易错点

  1. 深浅拷贝混淆

◦ 直接赋值是浅拷贝(共享引用):

const a = [1, 2];
const b = a;
b.push(3); // a 变为 [1,2,3]2,5

◦ 深拷贝方案:JSON.parse(JSON.stringify(obj))(忽略函数/Symbol)或递归克隆。

  1. 浮点数精度问题

0.1 + 0.2 !== 0.3(IEEE 754 双精度浮点限制),需用 toFixed(2) 处理显示。

  1. 数组遍历的坑

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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913638.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913638.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UNIX程序设计基本概念和术语

unix体系结构从严格意义上说&#xff0c;可将操作系统定义为一种软件&#xff0c;它控制计算机硬件资源&#xff0c;提供程序运行环境。我们通常将这种软件称为内核&#xff08;kernel&#xff09;&#xff0c;因为它相对较小&#xff0c;而且位于环境的核心。内核的接口被称为…

【WEB】Polar靶场 16-20题 详细笔记

目录 十六.签到题 十七.签到 十八.session文件包含 PHP 伪协议&#xff08;PHP Stream Wrappers&#xff09; base64加解密获取源代码 Session文件包含 namenameShell 是什么&#xff1f; 十九.Dont touch me 二十.robots robots.txt 十六.签到题 把didino改成didiy…

数据结构*搜索树

什么是搜索树 搜索树是一种树形数据结构&#xff0c;用于高效地存储和检索数据。其核心特点是每个节点包含一个键&#xff08;Key&#xff09;&#xff0c;并遵循特定的排序规则。常见的搜索树有二叉搜索树、自平衡二叉树、多叉搜索树等。AVL树、红黑树、Splay树都属于自平衡二…

语音交互新纪元:Hugging Face LeRobot如何让机器人真正“懂你”

机器人之言&#xff1a;早在2024年&#xff0c;Hugging Face正式进军真实世界机器人应用领域&#xff0c;推出了开源机器人项目LeRobot。LeRobot不仅仅是一个模型库&#xff0c;它是一个完整的机器人学习平台&#xff0c;融合了模仿学习、强化学习、数据可视化以及仿真环境。其…

搭建个人博客系列--MySql

前期提要&#xff1a;搭建个人博客系列--docker-CSDN博客 目前已经拥有了docker所以只需要将MySql安装在docker上即可。 一、在docker安装mysql docker pull mysql 二、查询docker内的mysql镜像 三、启动msql docker run -d -p 33060:3306 -v /home/mysql/conf:/mysql/conf.d…

【Spring】Spring Boot + OAuth2 + JWT + Gateway的完整落地方案,包含认证流程设计

Spring Boot OAuth2 JWT Gateway的完整落地方案&#xff0c;包含认证流程设计网关在服务中的使用一、整体架构设计二、核心组件实现1. OAuth2认证服务器&#xff08;auth-service&#xff09;2. JWT自定义增强&#xff08;存储用户信息&#xff09;三、Gateway全局拦截&…

第一个小程序

一、前言随着移动互联网的发展&#xff0c;用户对“即用即走”的轻量级应用需求日益增长&#xff0c;而传统 App 在下载安装、更新维护等方面存在一定的门槛。小程序应运而生&#xff0c;它是一种无需下载即可使用的应用程序形态。本文将带你完成人生中第一个微信小程序的开发全…

【办公类-54-07】20250901 2025学年第一学期班级点名册模版(双休国定假涂成灰色、修改标题和页眉,批量导出PDF)

背景需求: 制作了校历单后,第二个要制作的就是点名册(灰色版) 【办公类-54-03】20240828班级点名册模版(双休国定假涂成灰色)2024学年第一学期_姓名周一到周五的点名册怎么画-CSDN博客文章浏览阅读2.1k次,点赞24次,收藏4次。【办公类-54-03】20240828班级点名册模版(…

iOS App首次启动请求异常调试:一次冷启动链路抓包与初始化流程修复

在一次 iOS App 大版本更新后&#xff0c;部分用户反馈首次打开 App 时会出现“无法连接服务器”的提示&#xff0c;需要重启 App 才能正常使用。而后续使用过程中接口调用都正常。服务器端并未记录请求到达&#xff0c;日志中只有 sporadic&#xff08;零星&#xff09;断连记…

【Linux网络篇】:网络中的其他重要协议或技术——DNS,ICMP协议,NAT技术等

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;Linux篇–CSDN博客 文章目录其他重要协议或技术1.DNS2.ICMP协议3.NAT技术4.代理服务器其他重…

HarmonyOS学习4 --- 创建一个页面

1、声明式UI语法Entry Component struct My_page {State isLogin: boolean falsebuild() {Row() {Image(this.isLogin ? $r(app.media.icon_leon) : $r(app.media.icon)).height(60).width(60).onClick(() > {this.isLogin !this.isLogin})Text(this.isLogin ? $r(app.s…

【Java EE】Spring MVC 的使用

1. 路由映射&#xff1a;RequestMapping&#xff1a;当用户访问某个 URL 时&#xff0c;该注解会根据 URL 的路径映射到具体的程序中对应的类或方法&#xff08;路由映射&#xff09;。修饰方法时&#xff0c;路径为类路径 方法路径。默认情况下同时支持 GET 和 POST&#xff…

pip 安装默认切换到国内镜像(清华园,阿里云等)

国内Python包镜像地址如下&#xff1a; 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple/阿里云&#xff1a;https://mirrors.aliyun.com/pypi/simple/中国科技大学&#xff1a;https://pypi.mirrors.ustc.edu.cn/simple/华为云&#xff1a;https://repo.huaweiclou…

AI agent 学习

参考&#xff1a; AI搜索DeepResearch&#xff1f;_大模型 deepsearch 深度搜索-CSDN博客 Agent是以大语言模型为大脑驱动的系统&#xff0c;具备自主理解、感知、规划、记忆和使用工具的能力&#xff0c;能够自动化执行和完成复杂任务。 自主性和自适应&#xff0c;是判断一款…

【PTA数据结构 | C语言版】求单链表list中的元素个数,即表长

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将 n 个整数顺次插入一个初始为空的单链表的表头。最后输出单链表的表长。 本题旨在训练学习者熟悉单链表的基本操作&#xff0c;不建议直接输出 n。 输入格式&#xff1a;…

玩转Docker | 使用Docker部署HomeBox家庭库存管理工具

玩转Docker | 使用Docker部署HomeBox家庭库存管理工具 前言一、HomeBox介绍Homebox简介主要特点主要使用场景二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署HomeBox服务下载HomeBox镜像编辑部署文件创建容器检查容器状态检查服务端口安全设置四、访问Hom…

QT中的常用控件-QWidget的enable属性

QT中的常用控件-QWidget的enable属性 enable描述了一个控件是否处于“可用”状态 与之相对应的概念是“禁用”&#xff0c;禁用是该控件不能接受任何用户的输入事件&#xff0c;并且外观上往往是灰色的 如果一个Widget被禁用&#xff0c;则该Widget的子元素也被禁用API说明IsEn…

【数据结构】复杂度分析

目录 一、算法 1.基本概念 2.描述方法 3.算法效率 二、算法的时间复杂度 三、算法的空间复杂度 一、算法 1.基本概念 通俗的讲&#xff0c;算法是解决问题的方法&#xff0c;比如在现实生活中一道菜谱&#xff0c;一个安装轮椅的操作指南等。 严格的说&#xff0c;算法…

推荐系统基础 --ShusenWang

学习b站up主的ShusenWang的推荐系统笔记 指标 任何系统/算法/模型都需要评估&#xff0c;对于推荐系统的指标有消费指标和北极星指标&#xff0c;消费指标是衡量用户对产品的使用情况&#xff0c;使用频率广度和深度&#xff0c;用于了解用户的使用习惯&#xff0c;北极星指标是…

linux wsl2 docker 镜像复用快速方法

GitHub项目中的devcontainer.json、Dockerfile构建了一个A项目的镜像环境&#xff0c;现在我有一个文件夹&#xff0c;文件夹中只有一个b.py文件&#xff0c;此时我希望使用A项目的环境&#xff0c;如何实现&#xff1f;注意&#xff1a; 建议使用下面的方法2 解决方案&#xf…