let、const和var的区别是什么?

文章目录

  • 一、概述
  • 二、var 的特点
    • 2.1、作用域
    • 2.2、提升(Hoisting)
    • 2.3、全局变量
    • 2.4、重复声明‌
  • 三、let 的特点
    • 3.1、作用域
    • 3.2、提升(Hoisting)
    • 3.3、不允许重复声明
  • 四、const 的特点
    • 4.1、作用域
    • 4.2、不可变性
    • 4.3、提升(Hoisting)
  • 五、总结
    • 5.1、总结与比较
    • 5.2、let和const解决了什么问题?为什么不继续用var了?
      • 5.2.1、var的起源
      • 5.2.2、var的问题与限制
  • 六、实践使用

一、概述

在JavaScript中,let、const 和 var 是用于声明变量的三种关键字。虽然它们的功能相似,但在作用域、提升、可变性以及使用方式等方面存在显著差异。理解这些差异对于编写高质量、可维护的代码至关重要。本文将详细探讨这三种关键字的区别。

在ES5及之前的JavaScript版本中,我们通常使用var关键字声明变量。

因为var声明的变量,内层变量可能覆盖外层变量的问题以及用来计数的循环变量泄露为全局变量;

所以在ES6之后,引入了 let 、 const声明变量。let和const的出现就是为了解决var的各种问题

我们来重点讨论var、let和const的区别;

二、var 的特点

在ES5及之前的JavaScript版本中,我们通常使用var关键字声明变量。var具有以下特点:

2.1、作用域

var 声明的变量具有函数作用域(function scope)。这意味着变量在声明它的函数内可见,或者在全局范围内可见,如果它是在函数外部声明的。

示例

function testVar() {
    var x = 10;
    if (true) {
        var x = 20; // 同一作用域
        console.log(x); // 输出: 20
    }
    console.log(x); // 输出: 20
}

testVar();

在这个例子中,x 在 if 语句块内被重新赋值,这影响了函数中的 x 变量。

2.2、提升(Hoisting)

var 声明的变量会被提升到其所在作用域的顶部,这意味着你可以在声明之前访问变量,但其值为 undefined。

示例

console.log(y); // 输出: undefined
var y = 5;
console.log(y); // 输出: 5

在这个例子中,虽然 y 的声明在 console.log() 之后,但由于提升,它仍然可以在调用之前访问,返回 undefined。

2.3、全局变量

在全局作用域中使用 var 声明的变量会成为全局对象的属性。在浏览器中,全局对象是 window。

示例

var globalVar = 'I am global';
console.log(window.globalVar); // 输出: I am global

2.4、重复声明‌

‌var‌:允许在同一作用域内重复声明变量,后声明的同名变量会覆盖之前声明的。

function example() {
	console.log(x); // undefined,因为变量提升
	var x = 10;
	console.log(x); // 10
	var x = 20; // 允许重复声明
	console.log(x); // 20
}

三、let 的特点

let关键字是在ES6中引入的新特性,具有以下特点:

3.1、作用域

let 声明的变量具有块作用域(block scope)。这意味着变量只在其所在的代码块内可见。

示例

function testLet() {
    let x = 10;
    if (true) {
        let x = 20; // 不同的作用域
        console.log(x); // 输出: 20
    }
    console.log(x); // 输出: 10
}
testLet();

在这个例子中,内部的 x 不会影响外部的 x,它们是不同的变量。

3.2、提升(Hoisting)

let 声明的变量同样会被提升,但在变量声明之前,访问它们会导致 ReferenceError。这被称为“暂时性死区”(Temporal Dead Zone)。

示例

console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 3;

console.log(x); //输出:3

在这个例子中,x在声明之前被访问会导致错误。

3.3、不允许重复声明

在同一作用域中,不能使用 let 重复声明同一个变量。

示例

console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 1;
let a = 2; // SyntaxError: Identifier 'a' has already been declared

四、const 的特点

const关键字也是在ES6中引入的新特性,与let相似,但具有以下特点:

4.1、作用域

const 的作用域与 let 相同,都是块作用域。

示例

function testConst() {
    const a = 10;
    if (true) {
        const a = 20; // 不同的作用域
        console.log(a); // 输出: 20
    }
    console.log(a); // 输出: 10
}

testConst();

4.2、不可变性

const 声明的变量必须初始化,且不能重新赋值。但对于对象和数组,虽然变量本身不能重新赋值,但其属性或元素可以修改

示例

const a = 5;
// a = 10; // TypeError: Assignment to constant variable.

const obj = { prop: 1 };
obj.prop = 2; // 允许修改对象的属性
console.log(obj.prop); // 输出: 2

在这个例子中,a 不能被重新赋值,但 obj 的属性可以被修改。

4.3、提升(Hoisting)

const 和 let 都会被提升,并且在声明之前访问也会导致 ReferenceError。

示例

console.log(a); // ReferenceError: Cannot access 'a' before initialization
const a = 5;

五、总结

5.1、总结与比较

特性varletconst
起源ES6之前ES6(ECMAScript 2015)ES6(ECMAScript 2015)
作用域函数作用域块作用域块作用域
提升是,值为 undefined是,暂时性死区是,暂时性死区
重新赋值允许允许不允许
重复声明允许不允许不允许
全局变量成为全局对象的属性不会成为全局对象的属性不会成为全局对象的属性

1.变量提升

  • var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
  • let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错

2.块级作用域

  • var不存在块级作用域
  • let和const存在块级作用域

3.重复声明

  • var允许重复声明变量
  • let和const在同一作用域不允许重复声明变量

4.修改声明的变量

  • var和let可以
  • const声明一个只读的常量。一旦声明,常量的值就不能改变,但对于对象和数据这种引用类型,内存地址不能修改,可以修改里面的值。

在现代 JavaScript 开发中,建议使用 let 和 const,尽量避免使用 var,因为它们提供了更严格的变量作用域和更可预测的行为。

5.2、let和const解决了什么问题?为什么不继续用var了?

5.2.1、var的起源

var关键字最初是在ECMAScript 1(1997年发布的ECMAScript标准)中引入的,用以支持基本的变量声明。随着ECMAScript标准的不断演进,JavaScript的功能得到了极大的增强和改进,但var作为最基本的变量声明方式之一,依然被保留。

5.2.2、var的问题与限制

尽管var有其用途,但它也有一些限制和潜在问题:

  • 全局变量污染:使用var声明的全局变量可能会覆盖已有的全局变量,导致意外的行为。
  • 函数作用域的提升:可能导致代码难以理解和维护,尤其是在复杂的函数中。
  • 块级作用域的限制:在块级作用域(如if语句、for循环等)中使用var声明的变量会提升到其函数作用域的顶部,而非其块级作用域。

现代替代方案:ES6引入了letconst来声明变量,提供了块级作用域(block scope),从而避免了这些问题。

使用let:适用于需要块级作用域的场景。

if (true) {
    let x = 5; // 只在if块内有效
}
console.log(x); // ReferenceError: x is not defined

使用const:适用于声明那些在初始化后不应改变其值的变量。

const PI = 3.14; // PI的值不能被重新赋值

总之,虽然var仍然在某些情况下可用,但在新的JavaScript代码中推荐使用let和const以提高代码质量和可维护性。

六、实践使用

1、使用 letconst:一般建议使用 letconst,避免使用 varconst 应该作为默认选择,除非需要在后续代码中重新赋值。

2、块作用域:利用 letconst 的块作用域来减少变量的生命周期,提高代码的可读性。

3、避免全局变量:尽量避免在全局作用域中使用 var,以减少潜在的命名冲突和污染。

4、使用 const 来声明常量:对于不会被重新赋值的变量,使用 const 来表明它的不可变性

因为letconst是es6的新特性,letconst的出现就是为了解决var的各种问题,强烈建议大家写js代码都用letconst声明变量和常量!




创作不易,欢迎打赏,你的鼓励将是我创作的最大动力。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数一考研复习之拉格朗日中值定理在求解函数极限中的应用,

最近在复习考研数学,只是简单做题过于乏味,因此便总结了一些笔记,后续若有空,也会将自己的复习笔记分享出来。本篇,我们将重点讲解拉格朗日中值定理在求解函数极限中的应用。同时,作者本人作为python领域创作者,还将在本文分享使用sympy求解高数中函数极…

Devart dbForge Studio for MySQL Enterprise 9.0.338高效数据库管理工具

Devart dbForge Studio for MySQL Enterprise 9.0.338 是一款功能强大的 MySQL 数据库管理工具,专为数据库开发人员和管理员设计。它提供了丰富的功能,帮助用户更高效地管理、开发和维护 MySQL 数据库 Devart dbForge Studio for MySQL Enterprise 9.0.…

Android15使用FFmpeg解码并播放MP4视频完整示例

效果: 1.编译FFmpeg库: 下载FFmpeg-kit的源码并编译生成安装平台库 2.复制生成的FFmpeg库so文件与包含目录到自己的Android下 如果没有prebuiltLibs目录,创建一个,然后复制 包含目录只复制arm64-v8a下

DeepSeek大模型 —— 全维度技术解析

DeepSeek大模型 —— 全维度技术解析 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家!点我试试!! 文章目录 DeepSeek大模型 —— 全维度技术解析一、模型架构全景解析1.1…

Spring Boot 与 MyBatis 版本兼容性

初接触Spring Boot,本次使用Spring Boot版本为3.4.3,mybatis的起步依赖版本为3.0.0,在启动时报错,报错代码如下 org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name userMapper…

JavaWeb6、Servlet

6.1Servlet简介 Servlet就是sun公司开发动态web的一门技术 sun公司在这些API中提供一个接口叫做Servlet,如果想开发一个Servlet程序,只需要完成两个小步骤: 编写一个类,实现Servlet接口 把开发好的Java类部署到web服务器中 把…

论文粗读——Isometric 3D Adversarial Examples in the Physical World

论文地址:Isometric 3D Adversarial Examples in the Physical World 动机 现有的3D点云攻击方法远远不够隐蔽,并且在物理世界中性能严重下降。 已有方法及其不足 基于梯度的攻击->仅限于数字世界攻击;KNN攻击和GeoA3攻击->点云重建引入了较大的噪声和错误,导致攻…

AI视频领域的DeepSeek—阿里万相2.1图生视频

让我们一同深入探索万相 2.1 ,本文不仅介绍其文生图和文生视频的使用秘籍,还将手把手教你如何利用它实现图生视频。 如下为生成的视频效果(我录制的GIF动图) 如下为输入的图片 目录 1.阿里巴巴全面开源旗下视频生成模型万相2.1模…

微电网协调控制器ACCU-100 分布式光伏 光储充一本化

安科瑞 华楠 18706163979 应用范围: 分布式光伏、微型风力发电、工商业储能、光储充一体化电站、微电网等领域。 主要功能: 数据采集:支持串口、以太网等多通道实时运行,满足各类风电与光伏逆变器、储能等 设备接入&#xff…

Android MVC、MVP、MVVM三种架构的介绍和使用。

写在前面:现在随便出去面试Android APP相关的工作,面试官基本上都会提问APP架构相关的问题,用Java、kotlin写APP的话,其实就三种架构MVC、MVP、MVVM,MVC和MVP高度相似,区别不大,MVVM则不同&…

懒加载预加载

(一)、懒加载 1.什么是懒加载? 懒加载也就是延迟加载。当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图)&#…

Python 中的析构函数:对象生命周期的终结艺术

在 Python 的面向对象编程中,析构函数是一个重要的概念。它主要用于在对象被销毁之前执行一些清理工作,如释放资源、关闭文件或网络连接等。本文将详细介绍 Python 中的析构函数,包括其定义、语法、调用时机以及实际应用场景。 一、什么是析…

使用QT + 文件IO + 鼠标拖拽事件 + 线程 ,实现大文件的传输

第一题、使用qss&#xff0c;通过线程&#xff0c;使进度条自己动起来 mythread.h #ifndef MYTHREAD_H #define MYTHREAD_H#include <QObject> #include <QThread> #include <QDebug>class mythread : public QThread {Q_OBJECT public:mythread(QObject* …

在 macOS 上使用 CLion 进行 Google Test 单元测试

介绍 Google Test&#xff08;GTest&#xff09;是 Google 开源的 C 单元测试框架&#xff0c;它提供了简单易用的断言、测试夹具&#xff08;Fixtures&#xff09;和测试运行机制&#xff0c;使 C 开发者能够编写高效的单元测试。 本博客将介绍如何在 macOS 上使用 CLion 配…

[MySQL初阶]MySQL(5)内置函数详解

标题&#xff1a;[MySQL初阶]MySQL&#xff08;5&#xff09;内置函数详解 水墨不写bug 文章目录 一、日期函数1. current_date()2. current_time()3. current_timestamp()4. date(datetime)5. date_add(date, interval expr unit)6. date_sub(date, interval expr unit)7. dat…

【MySQL】事务(隔离性、MVCC)

文章目录 1. 事务的概念2. 事务的提交方式3. 事务常见操作4. 隔离性4.1 隔离级别4.2 查看与设置隔离性4.3 隔离级别的测试 5. 隔离性的原理5.1 MVCC5.1.1 3个隐藏字段5.1.2 undo日志5.1.3 模拟MVCC 5.2 Read view5.3 RR与RC的本质区别 1. 事务的概念 在之前所有的SQL操作中&am…

单细胞分析(22)——高效使用 Cell Ranger:安装、参数解析及 Linux 后台运行指南

高效使用 Cell Ranger&#xff1a;安装、参数解析及 Linux 后台运行指南 背景介绍 Cell Ranger 是 10x Genomics 开发的一套用于单细胞转录组测序数据处理的软件。它可以对 10x Genomics 平台生成的 FASTQ 文件进行对齐、UMI 计数和基因表达量计算&#xff0c;是单细胞 RNA-se…

IEEE paper submission

author guideline IEEE 文章模板&#xff1a;https://template-selector.ieee.org/ 1&#xff09;Manuscripts that exceed eight pages will incur mandatory over-length page charges. (超过 8 页强制收费 $175/page) 2&#xff09;Authors are invited to submit manus…

NET431-C协议网关:跨网段·零编程PLC工业通信终极方案

系统框架图解析 三层架构&#xff0c;一图读懂&#xff1a; 设备层&#xff1a; 4个网口2个网段&#xff1a;直连AB、西门子、三菱等18台PLC&#xff0c;覆盖4个网段&#xff08;如10.1.1.0/24、192.168.2.0/24&#xff09;&#xff0c;协议转换。5路RS485串口&#xff1a;通过…

nvm 让 Node.js 版本切换更灵活

有很多小伙伴前端开发进程中&#xff0c;我们常常会遇到不同项目依赖不同版本 Node.js 的情况。我们不可能去卸载重新安装适应的版本去安装依赖或者启动项目。为了避免版本冲突带来的一系列麻烦&#xff0c;在这里给大家推荐一款Node.js 版本管理工具——nvm&#xff08;Node V…