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

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声明变量和常量!




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

在这里插入图片描述


http://www.kler.cn/a/576326.html

相关文章:

  • Unity自定义区域UI滑动事件
  • 【第19节】C++设计模式(行为模式)-Command(命令)模式
  • ECharts中yAxisIndex的作用
  • Java面试第十山!《Mybatis框架》
  • 鸿蒙应用开发深度解析:API 14核心特性与实战指南
  • 低空经济快速发展,无人机人才培养及校企实验室共建技术详解
  • Java UDP 通信:实现简单的 Echo 服务器与客户端
  • c#结合IL(中间语言)分析Try-Catch的内部机制及其对性能的影响
  • 信奥赛CSP-J复赛集训(模拟算法专题)(4):P1046 [NOIP 2005 普及组] 陶陶摘苹果
  • 小程序事件系统 —— 32 事件系统 - 事件分类以及阻止事件冒泡
  • 物联网 铁路“一杆一档”管理模式
  • v-code-diff 配置
  • HTML 属性详解:为网页元素赋予更多功能
  • 设计模式--单例模式(Singleton)【C++】
  • 分布式存储学习——HBase概述
  • linux上安装redis[从0到1]
  • Jenkins在Windows上的使用(二):自动拉取、打包、部署
  • 【uniapp】图片添加canvas水印
  • FFmpeg入门:最简单的音视频播放器
  • Docker 部署