ES6基础
一、新增命令let/const
①:let命令
1、let命令用来声明变量,它的用法类似于var,但是所声明的变量只在let命令所在的代码块内生效。
所以在for循环中,就很适合使用let命令。
上面代码中,i只在for循环体内有效,在循环体外就会报错。
在下面代码中,如果使用var,最后结果为 10。
上面代码中,变量i是var命令声明的,在全局范围内都有效,所以全局变量只有一个i。每一次循环,变量i的值都会被重新赋值,而循环内被赋给数组a
的函数内部的console.log(i)
,里面的i
指向的就是全局的i
。也就是说,所有数组a
的成员里面的i
,指向的都是同一个i
,导致运行时输出的是最后一轮的i
的值,也就是 10。
如果是用let,声明的变量仅在会计作用域内有效,结果也就为6.
上面的代码中,变量i是let声明的,所以i只会在本循环体中有效,因此每一次循环的i都是一个新的变量,也就是说会被重新赋值,所以结果也就为6。
另外,在for循环体中还有一个特别之处,就是设置循环变量的那一部分是一个父作用域,而循环体内是一个单独的子作用域。
2、变量不会被提升
在var命令中会发生‘变量提升’的现象,即变量可以在声明之前使用,值为undefined。
而let命令改变了这一语法行为,在声明之前使用会报错。
3、暂时性死区
何为暂时性死区?就是说只要块级作用域内存在let命令,它所声明的变量就‘绑定’这个区域,不再受外部的影响。
上面的代码中,存在全局变量a,但是在块级作用域内let又声明了一个局部变量a,导致后者绑定了这个区域,所以在let声明变量之前,对a的输出会报错。
在 ES6 中明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了一个封闭作用域。凡是在声明之前使用这些变量就会报错。
4、不允许重复声明
在var中,我们知道对于一个变量,可以用var去重复声明它。而在let中,不允许在相同的作用域内,重复声明同一个变量。
②:const命令
1、const声明一个只读的常量,一旦声明,常量的值就不能被改变。
因为const声明的变量不能更改,所以说,const一旦声明变量,就必须立即初始化,不能留到最后再去赋值。
上面代码表示,const只声明不赋值,就会报错。
2、const的作用域与let命令相同:只在声明所在的块级区域内有效;
3、const命令声明的常量也是不提升的,同样存在暂时性死区,只能在声明的位置后面使用,且同样不能被重复声明。
当然const实际上保证的并不是变量的值不被改变,而是变量指向的那个内存地址所保存的数据不被改变。而对于其他类型的数据(对象、数组),变量指向的则是内存地址,保存的只是一个指向实际数据的方位,const只能保证这个方位是固定的,至于它指向的数据结构是不是可变的,就不是能控制的了。
上面代码中,常量arr储存的是一个地址,这个地址指向一个数组。不可变的是这个地址,即不能把arr指向另一个地址,但数组本身是可变的,所以依然可以向里面添加值。
二、解构赋值
在ES6中,允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这个被称之为解构。
以前给变量赋值时,只能直接指定值。
在ES6中允许写成这样
上面代码中表示,可以从数组中提取值,按照对应的位置,对变量赋值。
只要等号两边的模式相同,左边的变量就会被赋予对应的值。
如果解构不成功,变量的值就等于undefined。
解构赋值允许指定默认值
这种情况下,只有当变量等于undefined时,默认值才会生效。
上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。
对象的解构赋值
解构也可以用于对象。
在对象的解构中,对象对策属性是没有次序之分的,只要变量与属性同名,就能取到正确的值。
在对象的解构中,我们还可以更改变量名。
上面代码中,foo是匹配的模式,bar才是变量,所以真正被赋值的是变量bar,而不是foo。
在对象的解构中也是可以指定默认值的,同样、条件必须是属性值等于undefined。