如何理解变量提升和 var、let、const间的区别

文章目录

      • 一、变量提升底层机制
      • 二、提升规则
      • 三、执行阶段表现
      • 四、变量提升特殊注意点
      • 五、变量提升最佳实践建议
      • 六、`var`、`let` 和 `const` 的核心区别对比
      • 七、关键差异详解
        • 1. 作用域范围
        • 2. 变量提升与暂时性死区(TDZ)
        • 3. 重复声明
        • 4. const 的特殊性
      • 八、最佳实践建议
      • 九、常见问题

JavaScript 变量提升(Hoisting)是编译阶段的特殊机制,其核心原理如下:

一、变量提升底层机制

1️⃣ 编译阶段处理

  • 在代码执行前,JS 引擎会先解析代码并创建执行上下文
  • 对所有声明语句(varfunction)进行预处理

2️⃣ 存储空间划分

// 编译阶段会创建变量环境(VariableEnvironment):
{a: undefined,      // var 声明b: function(){...} // function 声明
}

二、提升规则

声明类型提升行为示例
var 变量声明提升到作用域顶部,值初始化为undefinedconsole.log(a); var a=1;undefined
function声明整个函数体提升可先调用再声明
let/const存在暂时性死区(TDZ)提前访问会报错

暂时性死区:暂时性死区(Temporal Dead Zone)是 ES6 中 let/const 声明的特性,指:从进入作用域到变量声明语句执行前的区域,此时访问变量会触发 ReferenceError。

三、执行阶段表现

// 原始代码
console.log(a);
var a = 1;// 实际执行逻辑等同于:
var a; // 提升声明
console.log(a); // undefined
a = 1; // 原地赋值

四、变量提升特殊注意点

  1. 函数优先级:函数声明提升优先于变量声明
console.log(foo); // 输出函数体,而非undefined
var foo = 1;
function foo() {}
  1. 重复声明覆盖(如下代码案例):
function b() {console.log("第一次调用");
}
function b() {console.log("第二次调用");
} // 后者覆盖前者
  1. 块级作用域影响(ES6+):
{let a = 1;var b = 2;
}
console.log(b); // 2
console.log(a); // ReferenceError

五、变量提升最佳实践建议

  1. 使用 let/const 替代 var 避免意外提升
  2. 函数优先用表达式写法:const fn = () => {}
  3. 避免在同一作用域重复声明同名标识符

💡 现代开发中应通过 ESLint 规则 (如 no-use-before-define) 来规避变量提升带来的潜在问题。


六、varletconst 的核心区别对比

特性varletconst
作用域函数作用域块级作用域块级作用域
重复声明✅ 允许❌ 禁止❌ 禁止
变量提升✅ 提升且初始化为undefined⚠️ 提升但存在 TDZ⚠️ 提升但存在 TDZ
初始化要求可后赋值可后赋值❗ 必须立即赋值
全局对象属性✅ (如 window.a)
重新赋值✅ 允许✅ 允许❌ 禁止(对象属性可修改)

七、关键差异详解

1. 作用域范围
// var:函数作用域
function testVar() {if (true) {var a = 1;}console.log(a); // 1(泄露到函数作用域)
}// let/const:块级作用域
function testLet() {if (true) {let b = 2;const c = 3;}console.log(b); // ReferenceErrorconsole.log(c); // ReferenceError
}
2. 变量提升与暂时性死区(TDZ)
// var 的变量提升
console.log(x); // undefined
var x = 5;// let/const 的 TDZ
console.log(y); // ❌ ReferenceError
let y = 10;
3. 重复声明
var name = "Alice";
var name = "Bob"; // ✅ 允许let age = 25;
let age = 30; // ❌ SyntaxErrorconst PI = 3.14;
const PI = 3.14159; // ❌ SyntaxError
4. const 的特殊性
const user = { name: "Tom" };
user.name = "Jerry"; // ✅ 允许(修改对象属性)
user = {}; // ❌ TypeError(禁止重新赋值)const arr = [1, 2];
arr.push(3); // ✅ 允许(修改数组内容)
arr = [4, 5]; // ❌ TypeError

八、最佳实践建议

  1. 优先使用 const
    声明后不需修改的变量(如配置项、数学常量)

  2. 需要重新赋值时用 let
    循环计数器、状态变量等

  3. 避免使用 var
    防止变量泄露和意外覆盖(ES6+项目)

  4. 注意循环陷阱

    // var 的陷阱
    for (var i = 0; i < 3; i++) {setTimeout(() => console.log(i)); // 输出 3, 3, 3
    }// let 的正确用法
    for (let j = 0; j < 3; j++) {setTimeout(() => console.log(j)); // 输出 0, 1, 2
    }
    

九、常见问题

  1. TDZ 的表现
    let/const 声明前访问会触发错误,而 varundefined

  2. 全局污染问题

    var globalVar = 1;
    console.log(window.globalVar); // 1let moduleVar = 2;
    console.log(window.moduleVar); // undefined
    
  3. 函数提升优先级
    函数声明优先于 var 变量提升:

    console.log(typeof func); // "function"
    var func = "变量";
    function func() {}
    

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

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

相关文章

咖啡点单小程序毕业设计(JAVA+SpringBoot+微信小程序+完整源码+论文)

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着社会的快速发展和…

Excel(函数进阶篇):Vlookup函数进阶、TAKE嵌套SORE函数、SUBTOTAL函数、INDIRECT函数

目录 Vlookup函数返回多列结果Vlookup函数多条件匹配Vlookup函数部分匹配TAKE函数嵌套SORT函数&#xff0c;提取排序数据SUBTOTAL函数&#xff1a;制作动态报表SUBTOTAL函数&#xff1a;创建连续编号INDIRECT函数Vlookup跨多表抓取数据INDIRECT函数常见跨表的错误Vloopup函数联…

大模型 VS 传统算法:人工智能时代的“新老对话“

大模型 VS 传统算法&#xff1a;人工智能时代的"新老对话" 在AlphaGo击败李世石、ChatGPT掀起全民AI热潮的今天&#xff0c;人们往往将"大模型"与"算法"混为一谈。但当我们深入技术内核时会发现&#xff0c;这二者恰似人工智能发展的两个平行宇…

【蓝桥杯每日一题】3.17

&#x1f3dd;️专栏&#xff1a; 【蓝桥杯备篇】 &#x1f305;主页&#xff1a; f狐o狸x 他们说内存泄漏是bug&#xff0c;我说这是系统在逼我进化成SSR级程序员 OK来吧&#xff0c;不多废话&#xff0c;今天来点有难度的&#xff1a;二进制枚举 二进制枚举&#xff0c;就是…

Matlab 汽车振动多自由度非线性悬挂系统和参数研究

1、内容简介 略 Matlab 169-汽车振动多自由度非线性悬挂系统和参数研究 可以交流、咨询、答疑 2、内容说明 略 第二章 汽车模型建立 2.1 汽车悬架系统概述 2.1.1 悬架系统的结构和功能 2.1.2 悬架分类 2.2 四分之一车辆模型 对于车辆动力学&#xff0c;一般都是研究其悬…

hackmyvm-Smol

信息收集 ┌──(root㉿kali)-[/home/kali] └─# arp-scan -I eth1 192.168.56.0/24 Interface: eth1, type: EN10MB, MAC: 00:0c:29:34:da:f5, IPv4: 192.168.56.103 WARNING: Cannot open MAC/Vendor file ieee-oui.txt: Permission denied WARNING: Cannot open MAC/Vendo…

深度学习项目--基于DenseNet网络的“乳腺癌图像识别”,准确率90%+,pytorch复现

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 如果说最经典的神经网络&#xff0c;ResNet肯定是一个&#xff0c;从ResNet发布后&#xff0c;很多人做了修改&#xff0c;denseNet网络无疑是最成功的…

基于x11vnc的ubuntu远程桌面

1、安装VNC服务 sudo apt install x11vnc -y2、创建连接密码 sudo x11vnc -storepasswd3、安装lightdm服务 x11vnc 在 默认的 GDM3 中不起作用&#xff0c;因此需要使用 lightdm 桌面管理环境 sudo apt install lightdm -y切换至lightdm&#xff0c;上一步已经切换则跳过该…

Git 常用命令完全指南:从入门到高效协作

文章需要结构清晰&#xff0c;涵盖从入门到进阶的常用命令&#xff0c;结合实例和注意事项&#xff0c;帮助用户快速掌握Git的核心功能&#xff0c;并应用到实际项目中 一、仓库初始化与基础操作 1. 创建与克隆仓库 # 初始化本地仓库 git init# 克隆远程仓库&#xff08;SSH方…

【运维自动化-标准运维】如何实现一个最简单的流程编排

流程编排是标准运维最核心的功能&#xff0c;通过将不同功能的原子插件在画布上可视化的拖拽编排&#xff0c;可以实现各种不同场景的跨系统工作流。标准运维流程 根据实际运维操作场景梳理出来的操作步骤&#xff0c;通过不同的流转逻辑&#xff08;并行、分支、条件并行&…

【DeepSeek】HTML Api调用(支持V3和 R1,多轮对话、流式输出、对话保存、markdown格式支持)

文章目录 一、项目结构二、功能支持三、使用方法四、待改进五、参数优化 ☘️ 项目地址&#xff1a;https://github.com/CQUPTLei/DeepSeek_HTML/tree/master 对话截图&#xff1a; 一、项目结构 C:\USERS\14134\DESKTOP\DEEPSEEK │ .gitignore │ DeepSeek.html # 所…

烽火HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包及注意点说明

之前发布过这个固件包&#xff0c;关于烽火HG680-KA&#xff0f;HG680-KB_海思HI3798MV310_安卓9.0_U盘强刷固件包详细说明一下&#xff0c;汇总总结一些常遇到的情况&#xff0c;这次固件会分开发布&#xff0c;以免混淆。 上一个帖子地址&#xff1a;烽火HG680-KA&#xff0…

蓝桥杯备赛(基础语法4)

冒泡排序 冒泡排序的思想 冒泡排序的思想是每次将最大的一下一下运到最右边&#xff0c;然后将最右边这个确定下来。再来确定第二大的&#xff0c;再确定第三大的... 对于数组 a [ ] ,具体的来说&#xff0c;每次确定操作就是从左往右扫描&#xff0c;如果 a [ i ] > a [ …

【算法】力扣 713题:乘积小于 K 的子数组之深入思考

文章目录 前言题目&#xff1a;乘积小于 K 的子数组参考思路方法一&#xff1a;滑动窗口方法二&#xff1a;二分查找 参考题解方法一&#xff1a;滑动窗口解法方法二&#xff1a;二分查找解法 深入思考浮点精度&#xff1f;right - left 1&#xff1f;二分法&#xff1f;哈希优…

超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction

1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术&#xff0c;广泛应用于医学影像领域。通过重建和可视化三维结构&#xff0c;3D超声能够显著提高诊断精度和效率&#xff0c;同时减少医生的脑力负担。本技术文档将详细阐述…

Docker 部署 Graylog 日志管理系统

Docker 部署 Graylog 日志管理系统 前言一、准备工作二、Docker Compose 配置三、启动 Graylog 服务四、访问 Graylog Web 界面总结 前言 Graylog 是一个开源的日志管理平台&#xff0c;专为实时日志收集、分析和可视化设计。它支持强大的搜索功能&#xff0c;并且与 Elastics…

【图论】并查集的学习和使用

目录 并查集是什么&#xff1f; 举个例子 组成 父亲数组&#xff1a; find函数&#xff1a; union函数&#xff1a; 代码实现&#xff1a; fa[] 初始化code: find code&#xff1a; 递归实现: 非递归实现: union code : 画图模拟&#xff1a; 路径压缩&#xff1a…

FPGA-流水灯

Quartus中使用Verilog实现 根据之前所学内容&#xff0c;打开Quartus 软件&#xff0c;新建FPGA项目文件&#xff0c;建立好空项目过后&#xff0c;选择Verilog HDL File&#xff0c;因为我们要使用Verilog代码实现仿真。 详细操作可参考往期博客&#xff1a; FPGA 实验报告&a…

React19源码系列之createRoot的执行流程是怎么的?

2024年12月5日&#xff0c;react发布了react19版本。后面一段时间都将学习它的源码&#xff0c;并着手记录。 react官网&#xff1a;react19新特性 https://react.dev/blog/2024/12/05/react-19 在用vite创建react项目的使用&#xff0c;main.tsx主文件都会有以下代码。 //i…

全网首创/纯Qt/C++实现国标GB28181服务/实时视频/云台控制/预置位/录像回放和下载/事件订阅/语音对讲

一、前言说明 用纯Qt来实现这个GB28181的想法很久了&#xff0c;具体可以追溯到2014年&#xff0c;一晃十年都过去了&#xff0c;总算是整体的框架和逻辑都打通了&#xff0c;总归还是杂七杂八的事情多&#xff0c;无法静下心来研究具体的协议&#xff0c;最开始初步了解协议后…