浅谈 var 与 let 作用域不同的原因

文章探讨了JavaScript中var和let的关键区别,主要集中在它们的作用域、声明提升以及全局声明的不同。var有声明提升特性,其函数声明作用于函数作用域,全局声明作用于全局作用域;而let则没有声明提升,产生块级作用域,并存在暂时性死区。此外,var允许重复声明,let在同一作用域内不允许。全局声明的var会成为window属性,let则不会。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.
众所周知,var 和 let 最大的区别是作用域:var 的函数声明作用于函数作用域、全局声明作用于全局作用域,而let 的声明范围是块级作用域
(对于作用域的详解可参考我的另一篇博客:【JS全局、函数、块级作用域】

为什么会有这样的区别呢?

1、var 和 let 的函数声明

我们都知道,变量的整个过程是:声明 => 初始化 => 赋值

var 具有声明提升的特点,会将变量的声明提升至函数顶部,并且会将变量初始化为undefined,但对于变量的赋值是无法提升的
因此下面的代码会输出undefined:

function top() {
	console.log(test)   //输出undefined
	var test = "测试"
	console.log(test)   //输出“测试”
	}

根据 var 的提升规则,这个函数实际等价于:

function top() {
	var test           //声明提升,且test被初始化为undefined
	console.log(test)  //输出undefined
	test = "测试"      //赋值未提升
	console.log(test)  //输出“测试”
	}

因此 var 不管声明在函数的哪个区域,其实都是声明在了函数的顶部,所以整个函数都能访问到该变量,故 var 是的函数声明是作用于函数作用域的。

但 let 并没有声明提升的特点,因此let 只作用于声明之后的块级区域。若在为 let 声明之前就使用该变量,即使在同一块级区域也会报错,这是因为造成了暂时性死区,而造成 let 暂时性死区的原因也恰恰是因为 let 没有声明提升。

.

2、 var 与 let 全局声明的区别

var 的全局变量是作用在全局作用域上的,而 let 的声明是块级的,想一想,但如果在全局作用域去声明 let 变量的话,是不是 let 声明的变量就和 var 一样作用在全局作用域了呢?

其实不是的,因为 var 声明的全局变量是会添加至 window属性上的,而 let 和 const 声明的变量并不会。所以在这种情况下虽然在“全局”确实可以使用 let 变量,但我们也不能说此时 let 的声明是全局作用域,而是伪全局作用域

换而言之,var 声明的全局变量作用范围是整个 window,而 let 声明的全局变量作用范围只是整个文件。

也正因为 var 声明的全局变量会成为 window 的属性,所以在声明提升时,如果是在函数作用域声明的 var 变量,则会将声明提升至函数顶部,如果是在全局作用域声明的 var 变量,则会将声明提升至window。

如以下代码,只有 var 声明的全局变量 name1 成为了 window 的属性,其他文件都可以通过 window.name1 拿到该变量,而 let 声明的全局变量 name2 和 var 声明的函数变量 name3 都不是 window 的属性。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

.

3、var 与 let 的冗余声明

除了作用域的区别,var 和 let 还有很大一个区别便是是否允许重复声明,var 是允许重复声明的,而 let 是不允许同一个块作用域中出现冗余声明的

但是要明白,此处说的不允许冗余声明,指的并不是声明类型,而是变量本身不允许重复声明。
即以下这种情况也会报错:

let age = 9;
var age = 10;  //不允许重复声明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值