【ES6】关于var, let和const的区别。let块级作用域理解,let暂时性死区。

目录

var, let和const的区别

var(es5-用于声明变量)

let(es6-用来取代var)

const(es6-用来声明常量)

1. let,const 和 var 有块级作用域的区别,但块级作用域是什么呢?

使用立即执行函数和闭包解决问题 👆

2. let暂时性死区


var, let和const的区别

var(es5-用于声明变量)

  1. 变量可以重复声明,打印出的是最后一次声明内容;let,const不能重复声明

  2. 变量声明会被提升;(函数的声明也会被提升)let,const不会提升

  3. var声明的变量没有局部作用域;let,const有块级作用域

let(es6-用来取代var)

  1. 不能重复声明;不会提升;有块级作用域

  2. 不影响作用域链

const(es6-用来声明常量)

  1. 不能重复声明;不会提升;有块级作用域

  2. 不能修改(对于数组和对象元素/属性的修改不算作常量修改。原因:该常量所指向的地址没有改变)

  3. const 使用场景:声明的匿名函数,箭头函数


1. let,const 和 var 有块级作用域的区别,但块级作用域是什么呢?

首先我们知道作用域分为:全局作用域,函数作用域,块级作用域。

块级作用域主要指:if / for

ES5中的var是没有块级作用域的(if / for)

ES6中的let是有块级作用域的(if / for)

举个例子来解释吧🌰

//var定义变量
for(var i = 0; i < 3; i++) { 
  setTimeout(function() {  
    console.log(i);       
  }, 0);
}
//结果:3,3,3

//let定义变量
for(let i = 0; i < 3; i++) { 
  setTimeout(function() {  
    console.log(i);       
  }, 0);
}
//结果:0,1,2

语法解释:

1. JS中的for循环体比较特殊,每次执行都有一个全新的独立的块作用域

2. var不支持块级作用域(var只有函数作用域和全局作用域),let支持块级作用域,所以let声明的变量只在它所在的代码块内有效。

执行过程:

定时器为异步执行,每次 for循环都将异步任务放入对应的管理模块,所以当满足条件将异步任务放入回调队列(callback queue)。for循环的执行速度很快,当 for循环执行完成之后 i=3,此时主线程任务执行完将回调钩回到主线程。

1. 对于var,不支持块级作用域,当将回调任务钩回主线程时,此时i=3,所以结果是3,3,3

2. 对于let,支持块级作用域,每个块内都有一个独立的i,当将回调任务钩回主线程时,每个任务输出对应块级作用域的i,结果是0,1,2

实际应用:循环遍历监听

<body>	
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>	
</body>

<script type="text/javascript">
    var btns = document.getElementsByTagName('button');
	for (let i = 0; i<btns.length; i++){	
    //for (var i = 0; i<btns.length; i++){
    	let btn = btns[i];                //结果:依次0,1,2,3,4			
    	//var btn = btns[i];              //结果:依次5,5,5,5,5       	
        btn.onclick = function(){    
            alert(i);		
        }    
	}	
</script> 

🪐 ps:ES6之前因为 if 和 for 都没有块级作用域的概念,所以很多的时候,我们必须借助函数作用域(即使用闭包)来解决应用外面的变量问题。

使用立即执行函数和闭包解决问题 👆

for(var i = 0; i < 3; i++) { 
    (function(i){
        setTimeout(function() {  
            console.log(i);       
        }, 1000);
    })(i)
}
<!--块级作用域应用:循环遍历加监听-->
<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
</body>
<script type="text/javascript">
	var btns = document.getElementsByTagName('button');
	for(var i = 0; i<btns.length; i++){	//for (var i = 0; i<btns.length; i++)
        (function(i){
        	var btn = btns[i];
        	btn.onclick = function(){
                alert(i);		          //∵使用了闭包∴拿到的i不是最后的3
            }    
        })(i)
	}
</script>

2. let暂时性死区

官方解释:在这运行流程进入作用域创建变量,到变量可以被访问之间的这段时间,称为暂时死区。

通俗理解:在let/const声明之前使用会报错,在let命令声明某变量之前,都属于该变量的死区范围。

let a;
console.log(a);		//Undefined
console.log(b);		//报错
let b;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值