es6 let&&const

JS的三大组成部分

  1. JS语法 --> ECMAScript -->es5 -->es6
  2. DOM --> Document Object Model(文档对象模型) 可以操作html+css
  3. BOM --> Browser Object Model(浏览器对象模型)

let/constvar的区别

es5es6中如何声明一个变量

如何声明一个变量(es5)

var a = 1;//var (es5)声明变量的关键词
console.log(a);

在这里插入图片描述
如何声明一个变量(es6)

let b = 1;//let (es6)声明变量的关键词
console.log(b)

在这里插入图片描述
声明变量letvar的区别

letvar关键词能否在同一个作用域中重复中声明一个变量吗??

var可以在同一个作用域中重复中声明一个变量吗??

var a = 1; 
var a = 2;
console.log(a);

在这里插入图片描述
var关键词:能够在同一个作用域中重复声明一个变量

let可以在同一个作用域中重复中声明一个变量吗??

let b = 1; 
let b = 2;
console.log(b)

在这里插入图片描述
会报错:SyntaxError表示语法错误 ,declared表示这个变量已经被声明过了。

let关键词:不能够在同一个作用域中重复声明一个变量

var声明的变量和用let声明的变量都是在本地占用内存的

那么用varlet声明的变量,会挂在全局window对象上面吗??

var声明的变量会挂在全局window对象上面吗??

var a = 2;
console.log(window.a);

局作用域中var声明的变量,会自动成为window对象的属性
在这里插入图片描述
let声明的变量会挂在全局window对象上面吗??

let b = 2;
console.log(window.b)

全局作用域中let声明的变量,不会自动成为window对象的属性
在这里插入图片描述

es5中用var关键词声明的变量会自动挂在全局window对象自动成为window对象上面的属性(首先你要身处于全局),这种声明变量的现象很诡异,那么es6中用let声明的变量就杜绝了这种现象(不合理现象)

es6let声明的变量,能够让全局对象更干净,一些不该有的变量不会成为全局对象上面的属性(es6let声明的变量让你的代码更严谨一些)

那么用varlet声明的变量,都会有变量提升吗??

var声明的变量会有变量提升吗吗??

console.log(typeof a);//typeof检测不存在的变量他是结果是undefined
var a = 2;//var 关键词会变量提升

在这里插入图片描述

/*
		  JS引擎会把这种情况拆解一下代码来解析

          var a;//第一步会把var声明的变量提升到最前面
          console.log(a);//第二步一个变量没有赋值那么就是under
          a = 2;//从新给变量a赋值

		*/

var声明的变量他是,用变量提升的

let声明的变量会有变量提升吗吗??

console.log(typeof b);//用let声明的变量,在声明变量之前的所有代码,如果使用了b那么就会报错
var b = 2;//let 关键词会变量提升

在这里插入图片描述
报错:引用错误 initialization表示b在初始化之前不能赋值(没有b这个变量)access表示通道,机会,使用权

let声明的变量他是,用变量提升的,在该变量之前称为暂时性死区 ==>TDZ(Template Dead Zone,暂时性死区的本质是变量已经在当前作用域中了,但是不能够使用

let b = b;
console.log(b);
/*
            JS引擎会把上面的代码解析成一下代码
            //在该变量之前称为暂时性死区(TDZ)
            let b;
            //TDZ暂时性死区的区域,还包括等号的右侧,如果在这个范围内使用变量b的话那么就会报错
            b = b;
            console.log(b)
		 */

es5中用var关键词声明的变量如果没有赋值那么结果是undefined

es6中用let关键词声明的变量如果没有赋值那么就会报错

那用var关键词和用let关键词,声明的变量能生成块级作用域吗??

那用var关键词,声明的变量能生成块级作用域吗??

if (true) {//块级作用域是像if这样存放代码的区域(这样的区域也可以理解为代码块)
		 	var a = 2;
		 }
		 console.log(a);
 /*
           JS引擎解析代码如下
           var a;//用var声明的变量不赋值,值是undefined
           if(true){//true为真走一下代码块
           	 var a = 2;//让变量提升的a从新赋值是 a = 2
           }
           console.log(a);//在全局window对象上面找到变量a值是2,打印2
		 */

es5中用var 关键词声明的变量不能够让{}生成块级作用域

那用let关键词,声明的变量能生成块级作用域吗??

 if (true) {//块级作用域是像if这样存放代码的区域(这样的区域也可以理解为代码块)
	     let b = 2;
  } 
  console.log(b);

通过let关键词声明的变量,那么这个let关键词就能让花括号{}自动的生成一个块级作用域,那么用let关键词声明变量,全局作用域的变量就不能访问,用let声明的块级作用域里面的变量(否则会报错)

es6中用let关键词声明的变量可以让{}生成块级作用域

块级作用域

什么是块级作用域??

es5只有全局作用域函数作用域es6又新增了块级作用域的概念

for循环的块级作用域

for(let i=0;i<5;i++){//用let声明的变量{}(代码块)自动成为块级作用域
	  let c = 0;
}
console.log(c);

在这里插入图片描述
会报错:当前没有c这个变量(没有定义c这个变量)

在全局作用域中,不能访问块级作用域里面的变量(否则就会报没有定义变量这个错误)

for循环中条件里面有,用let声明的变量的i,那么这个i是身处于哪个作用域里面??

验证1

如果i是在全局作用域里面,那么就会打印5

for(let i=0;i<5;i++){
		let c = 0;
 }
 console.log(i);

在这里插入图片描述
报错:说明没有定义i这个变量(没有i),那么这个i不是在全局作用域里面,因为在全局作用域里面没有找到这个变量i(变量i不是在全局作用域里面)

验证2

那么是不是在这个for循环里面的{}块级作用域里面呢

for(let i=0;i<5;i++){
		let i = 'huasheng';
 }

如果i是在块级作用域里面,那么同一个作用域不能声明同一个变量(否则就会报错)结果是报错
在这里插入图片描述
当前没有打印任何数据,说明这个i不在for循环里面{}块级作用域里面

那么不在全局作用域,也不在for循环的{}块级作用域里面,那么他就是在for循环的()里面是有一个块级作用域的,说明了变量i就是在for循环的()里面自己形成了一个作用域

for循环中,不仅{}会生成块级作用域,()也会生成块级作用域

那么看一下案例

为什么用var关键词声明的变量i会打印5次5??

for(var i=0;i<5;i++){
	  setTimeout(function(){
			console.log(i)
	  },1000);
 };

在这里插入图片描述
首先是for循环他是可以会很快的执行完的,然后你开一个定时器1秒钟执行一次回调函数,回调函数内部要打印i,回调函数是没有i的我自然要去父级作用域去找i,而这个函数的作用域父级作用域是全局作用域,我会找全局的i而这个全局的ifor循环结束后的i(i=5),那么就会执行for循环代码在1秒后就打印5次5

那用let关键词声明的变量,打印的结果是什么

for(let i=0;i<5;i++){
	 setTimeout(function(){
			console.log(i)
	 },1000);
};

在这里插入图片描述

i=0 0<5  回调函数
i=1 1<5  回调函数
i=2 2<5  回调函数
i=3 3<5  回调函数
i=4 4<5  回调函数
i=5 5<5  5<5=false 条件为假条出for循环

let关键词声明变量,()号里面是有个块级作用域的{}号里面也是有一个块级作用域的

当定时器的回调函数里面要打印i,现在回调函数是在块级作用域中,这个块级作用域中是没有i的那我会顺着()括号这个块级作用域去找(父级),而父级作用域里面是有i的所以说我找到了,在回调函数打印i的时候其实就找到了()括号作用域里面的i值是0,如此循环反复5圈

回调函数所处环境就是{}号块级作用域内,这个块级作用域所处的环境是()号块级作用域中,所以说就连成一条链。

这个回调函数所处的环境不像var声明的变量了,var是在全局作用域中,但是let声明的变量不一样,let就延长了匿名函数的作用域链,匿名函数所处环境–>{}块级作用域–>()作用域–>全局作用域(这是一条作用域链被延长了)

那么用闭包怎么整呢??

for(var i=0;i<5;i++){
		(function(i){
			setTimeout(function(){
				console.log(i)
			},1000)
		})(i)
	 }

用闭包也是延长这个回调函数的作用域链,让这个回调函数所处的环境是在这个立即执行函数中存储了变量i也是延长了作用域链

在这里插入图片描述
现在用es6新增的let声明变量就可以,自动的延长作用域链了

单独的{}也会生成块级作用域的

 {//用let声明变量的话他会让{}生成一个块级作用域的
	  let b = 2;
 }
 console.log(b);//在全局作用域里面不能使用用let关键词生成块级作用域里面的变量的(否则会报错)

在这里插入图片描述

 let b = 2;//全局作用域的变量b
     {
		let b = b;//用let声明的变量自动成为块级作用域
		console.log(b)
     }

在这里插入图片描述
首先等号右侧你要使用变量blet是用变量提升的然后,let是有占时性死区的特性(变量b的前面和变量b的右侧),所以你使用打印变量b就会报错

const

const的作用:const关键词是用来声明变量的。 ==>举个例子 圆周率 光速 等不会改变的量

const在声明常量的同时必须要赋值,不然会报错

const PI =  Math.PI; //圆周率就是常量
		 //现在定义一个常量PI就是存放着Math.PI这个圆周率的,
		 //这个常量是不会变换的(声明的常量是不能让值变换了)否则会报错(表示不能被修改)

const声明常量的两个情况

如果该常量是 原始值则该常量不能被修改

 const num = 10;
 console.log(num);//正常情况系打印常量num

在这里插入图片描述

 const num = 10;
		 num = 12;
		 console.log(num);//改变把原始值赋值给常量,然后在改变这个原始值

在这里插入图片描述
表示使用const赋值错误 (赋值给常量变量)

如果该常量是 引用值,可以 保证在不修改常量地址的情况下,是可以 修改常量的数据结构

const PI =  [1,2];  
PI.push(3);//只要不改变常量存放的地址不被更改,那么就不会报错 push方法是不改变原来的数组的
console.log(PI)

在这里插入图片描述

 const PI = [1,2];//原先PI的地址是[1,2]这个数组
 PI = [3];//现在是新赋值了一个数组,把这个新的数组的地址有给了PI,
 //这个常量存放这另一个引用的地址那么自然就会报错

在这里插入图片描述
varlet的区别,就是,varconst的区别

,逗号运算符

  1. 使用逗号操作符(,)可以在一条语句中执行多个操作
  2. 逗号操作符多用于声明多个变量
  3. 在用于赋值时,逗号操作符总会返回表达式中的最后一项
 var num=(5,'name',false,null,undefined,[1,2],{});
 console.log(num)
 //num的值为{}在这种情况下必须写()否则会报错
 //由于0是表达式中的最后一项,因此num的值就是0

在这里插入图片描述
练习题目

for(let i = (setTimeout( function(){console.log(i)} , 2000) , 0); i<2; i++){};//打印出来是0

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值