前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >重学红宝书,再走长征路!var、let、const的区别

重学红宝书,再走长征路!var、let、const的区别

作者头像
萌萌哒草头将军
发布于 2025-02-19 03:06:48
发布于 2025-02-19 03:06:48
10100
代码可运行
举报
文章被收录于专栏:前端框架前端框架
运行总次数:0
代码可运行

基础好是你的谎言

好久之前读完了两遍红宝书第三版,所以一直洋洋得意自己基础好,

但是经过这次的字节抖音面试,真的体会到了什么是基础不好,我盲目的自信像极了人类面对三体水滴飞船时,坚信这是三体人送来的礼物一样愚蠢。

毁灭你与你何干!

痛定思痛,打算重新读一遍红宝书(第四版),并且将每天的阅读笔记记录下来,所以这是重走长征路系列的第一篇。期待我后面输出的同学可以关注一波~

文章同步在公众号:萌萌哒草头将军

letvar 的区别

函数作用域,可以冗余声明,变量提升

块级作用域,无法荣冗余声明,没有变量提升,但是有暂时性死区

作用域的区别

块级作用域仅仅在代码块里起作用,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (true) {
    let age = 10;
    console.log(age) // 10
}
console.log(age) // 语法错误

但是换做var则可以访问。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (true) {
    var age = 10;
    console.log(age) // 10
}
console.log(age) // 10

函数作用域仅仅在函数内部起作用,函数外部无法访问,如果换做let也无法访问,因为函数也是个代码块。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function add () {
    var age = 10
}
console.log(age) // 语法错误
变量提升暂时性死区

变量提升:指变量声明之前可以访问变量的行为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(name) // undefined
var name = "mmdctjj"

暂时性死区:变量声明之前无法访问的行为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onsole.log(name) // 语法错误
let name = "mmdctjj"
冗余声明

可以冗余声明的情况

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var name = "萌萌哒草头将军"
var name = "mmdctjj"

无法冗余声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let name = "萌萌哒草头将军"
let name = "mmdctjj" // 语法错误:name已经声明了

而且这种报错不会因为混用受影响

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var name = "萌萌哒草头将军"
let name = "mmdctjj" // 语法错误:name已经声明了
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let name = "萌萌哒草头将军"
var name = "mmdctjj" // 语法错误:name已经声明了

但是在不同代码块之间可以重复声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 仅做代码演示,不建议这么声明变量
if (local === "zn-Ch") {
    let name = "萌萌哒草头将军"
} else {
    let name = "mmdctjj"
}
全局声明的一些差异

var会将变量挂载到window对象上

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var name = "mmdctjj"
window.name === name // true

但是let则不会

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let name = "mmdctjj"
window.name // undefined

另外,如果省略声明变量的关键字,那么默认会使用var声明,也就是说

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
people = "a"
window.people === people // true
局部声明的一些差异

在函数中使用var声明一个变量,在执行函数后,该变量会保存在window对象上

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function test() {
    myName = "mmdctjj"
}
test()
myName // "mmdctjj"
window.myName // "mmdctjj"

let依然不会。造成这种差异的原因:变量提升

for循环中的一些差异

var在循环时会将变量溢出到外部

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (var i = 0; i < 5; i ++) {}
console.log(i) // 5

let则不会

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (let i = 0; i < 5; i ++) {}
console.log(i) // 语法错误:i未定义

另外会导致超出预期的行为

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (var i = 0; i < 5; i ++) {
    setTimeout(() => console.log(i), 0)
}
// 预期:0,1,2,3,4
// 实际:5,5,5,5,5
```可能
但是`let`不会
```js
for (let i = 0; i < 5; i ++) {
    setTimeout(() => console.log(i), 0)
}
// 实际:0,1,2,3,4

const 使用

基本的使用差异

constlet十分相似,不同的是,const声明变量时必须对值进行初始化赋值,且值无法被修改。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const name; // 语法错误: Missing initializer in const declaration
const people = "mmdctjj"
const people = "萌萌哒草头将军" // 语法错误
const age = 18
people = "萌萌哒草头将军" // 语法错误
age = 19 // 语法错误

我们知道变量保存基本变量类型时,只保存值,所以当用const声明一个基本类型,意味着无法被修改。

如果值为引用类型,也不能修改变量的引用地址。所以下面的修改都会报错

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const people = {}
people = {} // 语法错误

但是当值为引用类型时,我们可以修改引用类型内部的属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const people = {
    name: "mmdctjj";
}
people.name = "萌萌哒草头将军";
无法在修改值的for循环中使用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (const i = 0; i < 5; i ++) {}
// TypeError: Assignment to constant variable.

但是如果不修改值的情况,则可以使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let i = 5
for (const j = 7; i < 5; i ++) {
    console.log(j)
}
// 7, 7, 7, 7, 7

这是因为迭代变量会自增。

for 循环中,迭代变量通常是一个数字计数器,通过自增操作来访问下一个元素。而在其他循环结构(如 for...offorEach)中,迭代变量会自动获得下一个元素,无需显式自增。

可以在for of for in中使用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (let key in {a: 1, b: 2}) {
    console.log(key)
}
// "a", "b"
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for (let value of [1, 2]) {
    console.log(value)
}
// 1, 2

这是因为for of for in会为每个变量声明新的变量,而不是重新赋值。

使用风格推荐

能不用var就不用var,能用const就用const,不需要修改的常量使用const,需要修改的变量使用let

最后

文章很多细节都是来自于红宝书,一些地方可能加入自己的理解,希望不会带来误解,有错误地方欢迎指正。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萌萌哒草头将军 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
var let 以及 const区别和用法(详解)
在ES5中,声明变量只有var和function两种形式。但是因为var声明的变量会有一定的缺点(内层变量可能覆盖外层变量的问题以及用来计数的循环变量泄露为全局变量),ES6提出了使用let和const声明变量,更加安全方便的提供我们声明变量。
玖柒的小窝
2021/11/03
7070
var let 以及 const区别和用法(详解)
var、let和const之间的区别
即 let和 const不需要先声明,再使用,否则会报错,而 var不需要先声明再使用,可以先使用后声明,不会报错,不过赋值的时候,值一直是 undefined
赤蓝紫
2023/03/11
1.4K0
var、let和const之间的区别
var和let/const的区别
let和 const是 ES6 新增的命令,用于声明变量,这两个命令跟 ES5 的 var有许多不同,并且 let和 const也有一些细微的不同,再认真阅读了阮一峰老师的文档后,发现还是有一些不知道的细节...
OBKoro1
2020/10/27
4060
var和let/const的区别
var,let,const三者的特点和区别
能用const的情况下尽量使用const,大多数情况使用let,避免使用var。 const > let > var const声明的好处,一让阅读代码的人知道该变量不可修改,二是防止在修改代码的过程中无意中修改了该变量导致报错,减少bug的产生。let声明没有产生预编译和变量提升的问题,先声明再使用可以让代码本身更加规范,let是个块级作用域,也不会污染到全局的变量声明。 最后说一点就是使用的场景说明:let一般应用于基本数据类型;const 一般应用于引用数据类型,也就是函数对象等。
青梅煮码
2023/02/18
3620
ES6中let、const和var的区别
let 的用法类似于 var,但所声明的变量只在 let 命令所在的代码块内有效(一个“{}”相当于一个代码块)
Leophen
2019/08/23
7170
JavaScript 中的 Var,Let 和 Const 有什么区别
在ES5中,顶层对象的属性和全局变量是等价的,用var声明的变量既是全局变量,也是顶层变量
@超人
2021/07/05
1.1K0
JavaScript 中的 Var,Let 和 Const 有什么区别
JS中var、let和const的区别详解
因为var声明的变量,内层变量可能覆盖外层变量的问题以及用来计数的循环变量泄露为全局变量;
訾博ZiBo
2025/01/06
6900
JS中var、let和const的区别详解
使用let/const定义变量的场景
在javaScript中,定义变量是一个非常常见的操作,在Es5中,通常使用var定义声明变量,而在Es6中新增了let和const关键字,也是用于声明定义变量
itclanCoder
2022/01/25
1.1K0
Js中var let const 区别
在ES6(ES2015)出现之前,JavaScript中声明变量就只有通过 var 关键字,函数声明是通过 function 关键字,而在ES6之后,声明的方式有 var 、 let 、 const 、 function 、 class ,本文主要讨论 var 、 let 和 const 之间的区别。
编程内马尔
2022/11/15
1.9K0
es6中的Let和Const详解
for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
用户10106350
2022/10/28
5760
var、let、const声明变量的区别
let和var声明变量的区别: 1.let所声明的变量只在let命令所在的代码块内有效。(块级作用域)
IT人一直在路上
2019/09/18
8900
你真的懂let和const吗?
在ES6之前我们脑海里应该只存在全局作用域和函数级作用域,没有块级作用域。那么为什么要引入块级作用域呢?
思梦php
2018/03/15
8540
你真的懂let和const吗?
React 语法之let和const命令
let命令 基本用法 ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。 { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 上面代码在代码块之中,分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。 for循环的计数器,就
xiangzhihong
2018/02/05
6.5K0
let 和 const 命令
for循环 设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
达达前端
2019/08/19
7510
JS中var、const、let区别
剁椒鱼鳞
2023/05/26
1.3K0
JS中var、const、let区别
ES6语法学习(let与var区别、块级作用域、const命令)
下面的代码中,变量i是var声明的,所以i是一个全局变量在全局范围内都有效,所以全局只有一个变量i,每一次循环i的值都会发生改变,被赋给数组a的函数内部的console.log(i)中的i指向全局的i,因此所有数组a的成员中的i指向的都是同一个i,导致运行时输出的是最后一轮的i值10
帅的一麻皮
2020/06/21
1.2K0
Js篇-面试13-var let const 的区别以及暂时性死区
如果区块(花括号)中存在let命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前就使用这些变量,就会报错,所以在代码块内,使用let命令声明变量之前,该变量都是不可用的
itclanCoder
2020/10/28
9070
Js篇-面试13-var let const 的区别以及暂时性死区
ES6常用新特性学习1-let和const
在ES6以前,变量的声明都是使用var关键字,且会进行变量声明提升。另外,我们曾经讲过,JS中是没有块级作用域的,这一点也带来了很多的不便。ES6 新增了let和var两个关键字,用来声明变量。下面我们就来看看他们的用法。
love丁酥酥
2018/08/27
4890
ES6相关概念及新增语法
ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。
星辰_大海
2020/10/27
3920
ES6相关概念及新增语法
JavaScript let和const不完全指北
let 声明是 ES6 中最广为人知的特性之一,它和 var 声明功能类似,都用于变量声明,但是有着不同的作用域规则。 var 声明的变量是基于词法作用域的,仍然可以在变量声明所在块的外部访问到该变量,并且不会抛出错误。
撸码那些事
2019/09/02
4780
相关推荐
var let 以及 const区别和用法(详解)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档