透彻const,let,var三者声明的区别

Var声明方式

Var声明的变量有以下特性,我们一一揭秘

1.重复声明

​ var声明的变量可以重声明,因为JS的执行顺序由上往下,因此后声明的会覆盖原声明

	var num = 1;
	var num = 2;
	console.log(num);//2

2.重新赋值

​ var声明的变量可以重新赋值,赋值后的覆盖原来的

	var num = 1;
 		num = 2;
 	console.log(num);//2

3.变量提升

​ 我们知道JS的执行顺序是由上往下,按照正常的逻辑如果我们在一个变量未声明之前就使用它肯定是报错的

​ 但是Var声明的变量存在变量提升的问题,如下

	console.log(num);//undefined
		var num;
		console.log(cont);//undefined
		var cont=2;

​ 第一个undefined可以理解,因为变量提升,但是没有赋值默认就是undefined

​ 第二个cont变量其真实顺序应是var cont -->console.log(cont) -->cont =2 因此得到的也是undefined

4.作用域规则

​ 我们知道JS有一个块级作用域,用“ {} ” 表示,意思就是在块级作用域里面的东西只在此块有效果,看招

​ 情况一:{}内的代码没有被执行,但是由于变量提升,因此num为undefined

​ 情况二:{}内的代码被执行了,因此num输出1

​ 情况三:函数不算块级作用域,它有自己的函数作用域,因此在函数内声明的变量为局部变量

​ 情况四:省略了关键字,num被声明为全局变量,因此在函数外也可以访问

​ 情况五:在for循环内声明的var i 竟然变成了全局变量,这种情况我们是不愿看到的

​ 情况六:理想应该是0到9,但是从情况五我们就知道在for内var声明的变量是全局作用域,循环内的延时

​ 函数还没有执行人家for循环就跑完了,i最后被赋予了10,因此10个延时函数得到的 i 的值都是10

​ 那怎么让其结果输出正常呢?解决:将延时函数用一个立即执行函数套住

​ 情况七:我们知道window是全局的,这里用var声明的变量会绑定全局作用域

情况一:		if(false){	
					var	num = 1;
				}
				console.log(num); //undefined
		
情况二:		if(true){	
					var	num = 1;
				}
				console.log(num);//1
		
情况三:		function fun(){	var num = 1;}
			   fun()
			   console.log(num);//not defind
		
情况四:		function fun(){	 num = 1;}
		       fun()
		       console.log(num);//1
		       
情况五:        for (var i = 0; i < 10; i++) {
                    ...
                }
                console.log(i); // 10
                
情况六:        for (var i = 0; i < 10; i++) {
    				setTimeout(function() { 
    					console.log(i); //10,10,10,10,10,10,10,10,10,10
    				}, 100 * i);
			  }   
              
情况七:	    var value = 1;
			  console.log(window.value); // 1      

let和const声明方式

1.重复声明

​ 两种声明方式都一样,无法重复声明

		let num = 1;
		let num = 2;
		var num = 3;
		console.log(num);//'num' has already been declared
		
		const value=1;
		const value=2;
		console.log(value); //'value' has already been declared

2.重新赋值

​ let声明的基本类型变量可以重新赋值

​ let声明的复杂类型变量可以重新赋值

​ const声明的基本类型变量无法重新赋值

​ const声明的复杂类型变量无法重新赋值

基本类型:		let num=1;
				num=2;
				console.log(num);//2
复杂类型:		 let num={name:'张三'};
		 		num={age:123};
		 		console.log(num.name);//undefined
				console.log(num.age);//123

基本类型		 const value=1;
				value=2;
				console.log(value); //Assignment to constant variable.
复杂类型:		 
	情况一		  const num={name:'张三'};
		 		num={age:123};
		 		console.log(num.age);//Assignment to constant variable
	
	情况二  	   const value={name:'张三'};
				 value.name="李四"
				 console.log(value.name);//李四
				 允许修改其属性,因为修改属性并未改变其地址指向,
				 就想人可以更换器官

3.变量提升

    console.log(bar); //not defind
    let bar;
    console.log(bar); //undefined
    
    console.log(num);Missing initializer in const declaration
	const num;
	console.log(num);Missing initializer in const declaration

4.暂时性死区

​ 我们知道用var声明的变量会提升,因此只要你声明了在哪个地方都能使用,虽然其值是undefined

​ 但是const声明的变量在声明到为其赋值之间是不可以使用的,称为暂时性死区,如下

		console.log(num);//Missing initializer in const declaration
		const num;
		console.log(num);Missing initializer in const declaratio

5.作用域规则

​ 情况一和情况二说明const和let声明的变量都是块级作用域,也没有变量提升

​ 情况三:在函数内声明其在函数内生效,这个var,let ,const都是一样

​ 情况四:用const或者let声明的变量不会绑定全局window

​ 情况五:因为const和let声明的变量有跨级作用域,因此结果not defined很符合逻辑

​ 情况六:为什么打印正常呢?因为let和const是块级作用域,而且不可重复声明,因此循环0到9的时候for循环

​ 相当创建了9个块级作用域,每个块级作用域都保存了一个 i 和延时函数,因此结果正常,而var声明的变量

​ 我们知道是没有块级作用域的,因此我们for循环0到9的时候实际上是 i 一直都在window这一个大作用域

​ 下重复声明并且赋值: 第一次:var i=0 =>执行循环体 ,第二次:var i=1 =>执行循环体

情况一:	  if(false){
			 	const num =1;
			 	let value=2;
             }
             console.log(num);//not defined
             console.log(value)//not defined
		 
情况二:	  if(false){
			 	const num =1;
			 	let value=2;
             }
             console.log(num);//not defined
             console.log(value)//not defined

情况三:		function fun(){	const num = 1;let value=2;}
			   fun()
			   console.log(num);//not defind
			   console.log(value);//not defind
			   
情况四:	    const num = 1;
			   let value = 2;
			   console.log(window.num); //undefined   	
               console.log(window.value); //undefined   
	
情况五:		 for (let i = 0; i < 10; i++) {//const声明也是一样
               		.......
                }
           		console.log(i); //not defined

情况六:        for (let i = 0; i < 10; i++) {//const声明也是一样
    				setTimeout(function() { 
    					console.log(i); //0,1,2,3,4,5,6,7,8,9
    				}, 100 * i);
			  }   
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值