let和var在for循环中的表现

es6 for循环中let和var区别详解 let和var区别: for(var i=0;i{ console.log(i);//5个5 },100) } console.log(i);//5 console.log('=============') for(let j=0;j{ console.log(j);//0,1,2,3,4 },100) } console.log(j);//报错 j is not defined 为什么 用let就可以显示正确结果,而var就不可以呢? var是全局作用域,有变 立即下载

var变量声明关键字

在ECMAScript3中,声明变量的关键字var用来在当前作用域中声明一个变量,作用域为函数作用域。

函数作用域:

// 函数
function a(){
	var i = 0;
	console.log(i) // i = 0;
}
console.log(i) // i is not define
// 块
{
	var j = 0;
	console.log(j)  // j = 0
}
console.log(j)  // j = 0;

上面可以看见,在函数中var声明的变量在函数外面是访问不到的,而在块中通过var声明的变量在块外面是能访问的,这就是说var是函数作用域,只有函数能约束他的作用范围,而代码块是做不到约束var定义变量的范围的。所以下面两个段代码效果是一样的

{
	var j = 0;
	console.log(j)  // j = 0
}
console.log(j)  // j = 0
// 根据变量提升原则可以改为下面的式子
var j;
{
	j = 0;
	console.log(j)  // j = 0;
}
console.log(j)  // j = 0;

上面两段代码可以看出,在代码块中通过var定义的变量其实就是定义在块所在作用域的变量。


let变量声明关键字

let声明的变量和var声明的变量就作用域问题就是,let声明的变量是块级作用域;
块级作用域:

// 和var声明变量的例子比较
{
	let i = 0;
	console.log(i)  // i = 0;
}
console.log(i) // error 

上面例子可以看出let和var的不同点,var在代码块中定义的变量是代码块所在作用域的活动对象上面创建,而let是在代码块本身这个活动对象上面创建的变量。也就是说let声明的变量会被代码块所约束。当然,在函数中,函数体的代码也是一个代码块包含的,所以函数作用域任然在,或者说函数就是代码块的作用域约束的。


他们在for循环中的表现呢。

首先我们知道在for循环中,异步打印循环变量得到的值是一样的,都是循环最后一次的i的值

for(var i = 0;i<10;i++){
	setTimeout(function(){
		console.log(i)
	},100)
}  // 输出全是10
// 输出全是10的原因是因为i是全局变量,最后访问的都是全局变量i,而每次循环改变i的值就是改变全局变量的值,故而输出值均为10
// 之前对于这种问题的解决办法是通过闭包来实现
for(var i = 0;i<10;i++){
	(function(){
		var j = i;
		setTimeout(function(){
			console.log(j);
		},100)
	}())
}  // 输出0123456789;

上面解决办法的闭包实现,其实就是通过函数来构建一个作用域,每个作用域存储不同的i值,然后异步调用的函数是通过作用域链的调用规则访问到他创建时所在作用域的变量,就是创建时j的值,而j的值是局部变量,所以就能打印出0123456789;

而let呢,因为他是块级作用域,在for循环中,很明显我们是能找到一个{}构成的代码块的

for(let i = 0;i<10;i++){
	setTimeout(function(){
		console.log(i)
	},100)
}  // 0123456789;

为什么使用let就成了这个样子呢,就是和let的块级作用域。解释就很简单了,因为每次循环都创建一个块级作用域,并且存上i的值,这里面的let定义的i值就是局部变量,所以每次循环改变的就是对局部变量赋值,访问也是根据作用域链规则访问局部变量i这样就得到了最后的结果。
同样的,还有一个例子就是当let定义在for循环之外呢

let i = 0;
for(;i<10;i++){
	setTimeout(function(){
		console.log(i)
	},100)
}  // 全是10;

不是说好let是块级作用域么,为什么又是一个全是10,因为这里let定义的地方就是全局作用域下啊,所以这里的i就是全局作用域,所以代码块对i就没有约束能力了,因为i是个全局变量,局部改变它的值就是改变全局变量的值,最后打印的i也是访问全局变量i打印其值,自然都是打印的同一个值。

举个例子

如果上面还没看懂,这里用多次自执行函数来模拟一下简单的for循环,比较let和var变量

// 类似简单for循环每次给循环给定义一个i并且赋值,因为var变量在块中并没有作用域约束,所以就是定义全局变量i,而重复声明一个同名变量,后面声明覆盖前面声明,所以最后i = 2,最后打印的访问的变量在局部找不到就向上级查找,找到全局变量i,均为2;
{
	var i = 0;
	setTimeout(function(){console.log(i)},100)  // i = 2
}
{
	var i = 1;
	setTimeout(function(){console.log(i)},100)  // i = 2
}
{
	var i = 2;
	setTimeout(function(){console.log(i)},100)  // i = 2
}	

// 因为let有块级约束,所以每一个代码块中的i都是局部变量,所以每次打印访问的局部变量均不相同,所以就是各自打印各自作用域链中的局部变量的i
{
	let i = 0;
	setTimeout(function(){console.log(i)},100)  // i = 0
}
{
	let i = 1;
	setTimeout(function(){console.log(i)},100)  // i  =1
}
{
	let i = 2;
	setTimeout(function(){console.log(i)},100)  // i = 2
}

// 和上面let定义变量做比较,因为var是函数作用域,这里用自执行函数来创建一个作用域来创建一个作用域与上面的let对比,最后结果一样。
(function(){
	var i = 0;
	setTimeout(function(){console.log(i)},100)  // i = 0
}());
(function(){
	var i = 1;
	setTimeout(function(){console.log(i)},100)  // i = 1
}());
(function(){
	var i = 2;
	setTimeout(function(){console.log(i)},100)  // i = 2

}())

// 同样,对于let定义在全局的情况下,看下面这个模拟。因为i是全局作用域,所以每次执行都是在给i重新赋值,当进程执行完毕之后,全局作用域的 i = 2;而最后打印中,因为局部并没有找到定义的i变量,所以顺着作用域链向上查找,找到了全局i = 2,所以最后打印的结果就是全为2
let i = 0;
{
	i = 0;
	setTimeout(function(){console.log(i)},100)  // i = 2
}
{
	i = 1;
	setTimeout(function(){console.log(i)},100)  // i = 2
}
{
	i = 2;
	setTimeout(function(){console.log(i)},100)  // i = 2
}

// 同样,我们可以用var来模拟上面这种情况,依然是借助自执行函数来完成
var i;
(function(){
	i = 0;
	setTimeout(function(){console.log(i)},100)   // 2
}());
(function(){
	i = 1;
	setTimeout(function(){console.log(i)},100)  // 2
}());
(function(){
	i = 2;
	setTimeout(function(){console.log(i)},100)  // 2
}());

关于作用域和作用域链

javascript作用域那些事

泛微E8流程监控指南:如何用SQL实时追踪审批节点状态? 本文详细介绍了如何利用SQL实时监控泛微E8系统中的审批流程状态,包括核心数据表结构解析、全链路监控SQL实战以及智能预警机制设计。通过数据库直接查询和状态关联分析,帮助企业快速定位卡顿节点,提升流程效率。适用于需要优化OA系统流程管理的企业IT人员和业务主管。 阅读详情

相关推荐

用PyTorch和snnTorch库5分钟搞定一个脉冲神经网络(SNN)手写数字识别Demo

本文详细介绍了如何使用PyTorch和snnTorch库快速搭建一个脉冲神经网络(SNN)手写数字识别Demo。通过模拟生物神经元的脉冲发放机制,SNN在低功耗场景中展现出独特优势。文章涵盖环境配置、数据预处理、模型构建、训练评估全流程,并提供了性能优化技巧和常见问题解决方案,帮助开发者在5分钟内实现高效的SNN应用。

weixin_29300931的博客 392

JavaScript变量篇01-1:for循环中的var和let

1.在for循环中使用var声明来初始化的话,循环变量会暴露在和for循环同一作用域下,导致循环结束后还能访问到循环变量,且访问到的变量值是经过循环迭代后的值。2.解决这个问题的方法如下:* 使用闭包将循环变量的值作为局部变量保存起来;* 使用ES6的let声明,将循环变量的作用域限制在for循环内部,初始化变量始终是for循环的局部变量,不能在外界被访问到。环变量会暴露在和for循环同一作用域下,导致循环结束后还能访问到循环变量,且访问到的变量值是经过循环迭代后的值。

发果叁 4366

PyTorch版Unet训练后别只看loss:手把手教你计算并可视化多类别语义分割的mIoU(附完整代码)

本文详细介绍了在PyTorch中使用Unet模型进行多类别语义分割后,如何计算和可视化mIoU(mean Intersection over Union)以全面评估模型性能。通过完整的代码示例和实用技巧,帮助开发者从loss优化转向更精准的区域分割评估,特别适用于医学图像分析等关键场景。

weixin_30906185的博客 435

var和let在for循环中的区别

var和let在for循环中的区别

ioncannontic的博客 737

CTS实战:如何用set_sense优化时钟树平衡(附ICC2避坑指南)

本文深入探讨了在时钟树综合(CTS)中,如何正确使用`set_sense`命令优化时钟树平衡,并对比了其与`set_disable_timing`的本质区别。通过实战案例详细解析了`-stop_propagation`和`-clock_leaf`参数的应用场景,并提供了ICC2工具中的关键避坑指南,帮助后端工程师精准控制时钟拓扑,避免时序分析漏洞。

weixin_28933797的博客 459

汇川伺服Modbus-RTU通讯实战:从帧结构解析到西门子PLC配置

本文详细解析了汇川伺服与西门子PLC通过Modbus-RTU协议进行通讯的实战步骤,包括帧结构解析、硬件连接、参数设置及PLC程序配置。通过具体案例和常见问题排查指南,帮助工程师快速掌握工业自动化中的通讯技术,提升设备调试效率。

weixin_33670713的博客 453

for循环中var与let的区别

当在for循环中使用var和let时,会导致不同的输出结果的主要原因是变量的作用域和闭包不同。

qq_65010070的博客 628

Matplotlib图片尺寸调整全攻略:从figsize到savefig的实战技巧

在数据可视化与科学计算中,图形尺寸控制是影响图表可读性与专业度的基础环节。其核心原理在于协调逻辑尺寸(英寸)与物理输出(像素)的映射关系,这直接决定了信息呈现的清晰度与布局合理性。从技术价值看,精准的尺寸控制能提升图表在不同媒介(如学术论文、报告、网页)中的适配性,避免显示不全、模糊失真等常见问题。在应用场景上,无论是Jupyter Notebook中的交互探索、自动化报告的批量生成,还是满足严格出版要求的插图制作,都需要掌握对应的尺寸调整策略。本文聚焦于matplotlib中的figsize参数、rcPa

weixin_30899023的博客 330

for 循环中的 let 声明和 var 声明

我们知道,ES6 之后,出现了 let 关键字。至此,块级作用域势如破竹,占据一席之地。 今天就好好聊一聊,块级作用域范畴中,for 循环里面 let 声明和 var 声明,有啥区别?

The world has changed because of technology! 757

鱼鹰优化算法(OOA)详解:从猛禽捕食智能到优化算法实现

鱼鹰优化算法(Osprey Optimization Algorithm, OOA)是2023年提出的一种新型元启发式优化算法,灵感来源于鱼鹰(一种中型猛禽)高效的捕食策略。算法模拟了鱼鹰从空中识别水下鱼类位置并俯冲捕食,然后将捕获的鱼带至安全位置享用的全过程,以此抽象出全局探索和局部开发两个核心阶段。OOA算法具有参数少、结构简单、收敛速度快、全局寻优能力强等特点。自提出以来,已在函数优化、机器学习参数调优(如CatBoost模型)、路径规划等多个领域展现出良好性能,为解决复杂优化问题提供了新的有效工具。

qq_42212808的博客 273

使用Simulink进行无刷电机霍尔传感器信号处理电路的仿真

位置检测:霍尔传感器可以检测转子的位置,这对于实现无刷电机的电子换向至关重要。提高效率:通过准确的位置信息,可以优化电机的工作状态,提高效率和性能。通过上述步骤,我们简要介绍了如何基于Simulink实现无刷电机霍尔传感器信号处理电路的仿真。

MHD0815的博客 431

var let 在 for 循环中的区别

let是块级作用域,只能在代码块中起作用,在js中一个{}中的语句我们也称为叫一个代码块,每次循环会产生一个代码块,每个代码块中的都是一个新的变量i;var是全局作用域,有变量提升的作用,所以在for中定义一个变量,全局可以使用,循环中的每一次给变量i赋值都是给全局变量i赋值。

m0_74359467的博客 288

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

let和var在for循环中的不同表现

var声明变量: var只有函数作用域,没有块级作用域 //函数作用域的表现 function test(){ var i =10; console.log(i); //10 } test(); //10 console.log(i); // i is not defined; //块级作用域对var没有约束 { var i = ...

ahdo26391的博客 396

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

let 和 var 在 for 循环中的表现

var 案例 for (var i = 0; i < 10; i++) { setTimeout(() => { console.log(i) }, 100) } 结果: 10 个 10 原因: 因为 i 是全局变量,最后访问的都是全局变量 i,而每次循环改变 i 的值就是改变后的全局变量的值,故而输出值为10 let 案例 for (let i = 0; i < 10; i++) { setTimeout(() => { console.log(i)

qq_31151699的博客 619

深入理解 JavaScript 中的 闭包、作用域与 var、let 在 for 循环中的行为

作用域决定了变量和函数的可访问性。在 JavaScript 中,作用域分为全局作用域、函数作用域和块级作用域。var和let声明的变量的作用域是不同的,var的作用域是函数作用域,而let的作用域是块级作用域。闭包是指一个函数可以记住并访问它外部函数的变量。即使外部函数已经执行完毕,闭包仍然可以访问和操作外部函数的变量。这是因为闭包会捕获外部函数的变量引用,而不是值本身。通过这篇文章,我们探讨了 JavaScript 中的作用域闭包var和let的差异,并理解了为什么在for循环中使用var。

一萧烟雨任平生 1375

var、let、const的区别

var 关键词 1. var声明作用域 var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问 function test() { var message = "hello world"; // 局部变量 } test(); console.log(message); // 报错 函数test()调用时会创建变量message并给它赋值,调用之后变量随即被销毁。因此,在函数test()之外调用变量message会报错 在函数内定义变量时省略var操作符,可以创建一个全局变量 func

weixin_42547971的博客 1万+

for循环中使用let跟var的区别

for循环中使用let跟var的区别 一般情况下var和let并没有太大区别,如果就是一个普通的循环且无太多需求的话 例如: for(var i = 0; i < 3; i++){ console.log(i) // 1 2 3 } for(let i = 0; i < 3; i++){ console.log(i) // 1 2 3 } 若果内部有异步执行函数的话,那么选择let就比选择var要好 例如: for (var i = 0; i < 3;

War__Tiger的博客 2840

一篇文章,带你了解for循环中let与var区别

首先来看个简单的例子,思考以下代码的输出有没有区别,这里运用到的知识点是函数作用域和块级作用域。这里输出是一样的 都是 0 ,1,2 ,但他并没有想象中的简单,我们来看一下他隐藏的知识点。举例: 思考以下的例子,想一下输出什么 答案:输出3,3,3 你想到了吗有的人可能恍然大悟,因为这是定时器啊,需要等待才能执行,但是i++已经先运行了所以输出3,3,3,那我再举个例子,我将定时器的时间设为0, 现在呢,答案是什么,你想到了吗答案:3,3,3这里的原因是因为,setTimeout是个异步执行的,计时器会被挂

qq_43635864的博客 889

es6种for循环中let和var区别

let和var区别: 1 for(var i=0;i<5;i++){ 2 setTimeout(()=>{ 3 console.log(i);//5个5 4 },100) 5 } 6 console.log(i);//5 7 console.log('=============') 8 9 for(let j=0;j<5;j++...

A-Select ° 331

for循环中关于var和let的区别

for 循环中的 let 声明 在 let 出现之前, for 循环定义的迭代变量会渗透到循环体外 部: for (var i = 0; i < 5; ++i) { // 循环逻辑 } console.log(i); // 5 改成使用 let 之后,这个问题就消失了,因为迭代变量的作用 域仅限于 for 循环块内部: for (let i = 0; i < 5; ++i) { // 循环逻辑 } console.log(i); // ReferenceError: i没有定义 在使用 va

weixin_52148270的博客 316

js面试题:let和var配合定时器中使用

一、let和var的区别 //let和var的区别相信列位已经耳熟能详了,在这里不做过多陈述,在第二段将用到的会提及一下 二、在定时器中的表现 var for (var i = 0; i < 5; i++) { setTimeout(function () { console.log("定时器" + i); }) } //5 * 定时器5 let for (let i = 0; i

weixin_44395929的博客 1043

前端js中var、let、const详解

var:1.声明变量的作用域限制于函数作用域2.变量的声明会被提升,总是被提升到函数作用域顶部let:1.声明变量的作用域限制于块级2.变量的声明不会被提升,处于“暂时性死区”const:1.声明变量的同时必须初始化,修改值时指针就会发生改变,要报错2.如果是复合类型,只修改某个value值是不会报错的。在开发过程中,程序员优先使用const,let次之,一般不使用var整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。

小王的技术库 5737

JavaScript中var、let、const的区别

var 关键词 1. var声明作用域 1.1 var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问 函数test()调用时会创建变量message并给它赋值,调用之后变量随即被销毁。因此,在函数test()之外调用变量message会报错 function test() { var message = "hello world"; // 局部变量 } test(); console.log(message); // 报错 1.2在函数内定义变量时省略var操作符,可以创建一个全局

m0_66333916的博客 3245

js for循环用 let 和 var比较

1.使用var 和 let 比较 因为var是全局变量,所以循环结束后值会被覆盖掉,比如初始值i=0;i<5那么最后循环结束后i的值就会也只能是5 let有作用域 在每次循环之前 会重新声明及初始化一次; for(var i = 0; i<5;i++){ // setTimeout(()=>console.log(i),0) // 5 5 5 5 5 } for(let i = 0; i<5;i++){ setTimeout(()=>console.log

bossxu_的博客 921

let与var区别大总结

目录 1. 函数作用域与块级作用域 2. 关于变量提升 3. 在for循环中的区别 4. 全局声明,var声明的会成为window对象的属性,let则不会 1. 函数作用域与块级作用域 在ES6出现之前,JavaScript是没有块级作用域的概念的。ES6的横空出世带来了let和const代替之前的var声明变量和常量,由此也带来了块级作用域的概念。 我们来看代码: { v...

追风Programer的博客 489
上一篇: Javascript作用域那些事
下一篇: 关于Vue背景图打包之后访问路径错误问题
white_g
博客等级 码龄10年 13粉丝 16原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值