一.let和const
1.var,let,const
块级作用域 | 变量提升 | 暂时性死区 | 禁止重复声明 | |
var | 无 | 有 | 无 | 无 |
let | 有 | 无 | 有 | 有 |
const | 有 | 无 | 有 | 有 |
块级作用域:ES5只有全局作用域和函数作用域,无块级作用域。ES6声明了块级作用域
变量提升:变量可以在声明前使用,且值为undefined
暂时性死区:只要块级作用域内存在let命令,它所声明的变量就绑定这个区域,不在受外部影响;声明之前不可获取。
- do表达式:使块级作用域可以返回值
let x=do{
let t=f();
t*t+1;
}
2.声明变量
ES5:var命令,function命令。顶层对象的属性和全局变量相关
ES6:var命令,function命令,let,const,import,class。var,function命令声明的全局变量依然是顶层对象的属性;let,const,class声明的全局变量不属于顶层对象的属性
二.变量的解构赋值
解构:ES6按照一定模式从数组和对象中提取值,赋给变量
解构赋值允许指定默认值。
1.数组
默认值生效条件:一个数组成员严格等于undefined
只要某个数据结构有Iterator接口,都可以采用数组的解构赋值
2.对象
内部机制:先找到同名属性,然后再赋值给对应变量
默认值生效条件:对象属性值严格等于undefined
3.字符串
const [a,b,c,d,e]='hello';
//字符串被转换成一个类数组对象
let {length:len}='hello';
//len=5
//利用length属性进行解构赋值
4.数值和布尔值
规则:先将其转换为对象。解构赋值,只有等号右边不是对象或数组,就将其转为对象或数组
5.圆括号问题
可以使用圆括号的情况:赋值语句的非模式部分可以使用圆括号
三.函数的扩展
1.函数参数的默认值
- ES6允许为函数的参数设置默认值
- 参数默认值可与解构赋值默认值结合使用
- 函数的length属性:返回没有指定默认值得参数个数
2.rest参数
形式:...变量名。用于获取函数的多余参数
- rest参数只能是最后一个参数
- 函数的length属性不包括rest参数
3.严格模式
只要函数参数使用了默认值,解构赋值或扩展运算符,那么函数内部就不能显示设置严格模式
4.name属性
name属性返回该函数的函数名
- 把匿名函数赋给一个变量,ES5会返回空字符串,ES6会返回实际函数名
- 将一个具名函数赋给变量,ES5和ES6都会返回具名函数原本的名字
5.箭头函数
var f=(num1,num2)=>{return num1+num2};
注意:
- 函数体内的this对象就是定义时所在对象,而不是使用时所在对象(箭头函数没有自己的this,导致内部的this就是外层代码的this)
- 不可以当做构造函数
- 不能使用arguments对象
- 不能使用yield命令,因此箭头函数不能用作Generator
6.绑定this
函数绑定运算符:(::)
foo::bar:将左边的对象foo作为上下文环境绑定到右边的bar函数上
7.尾调用优化
尾调用:在某个函数的最后一步调用另一个函数
尾调用优化:函数调用会在内存形成一个调用记录,又称调用帧,用来保存调用位置和内部变量等信息,所有的调用帧会形成一个调用栈。尾调用由于是函数的最后一步操作,就不需要保留外层函数的调用帧,只保留内部函数的调用帧
四.数组的扩展
1.扩展运算符(...)
作用:将一个数组转为用逗号分隔的参数序列
应用:
- 合并数组
- 与解构赋值结合起来,生成数组
- 字符串:可以将字符串转为真正的数组
- 对实现了Iterator接口的对象,可用扩展运算符转为数组
- Map,Set,Generator
2.Array.from()
作用:可把类数组对象和可遍历对象转为真正的数组
3.Array.of()
作用:将一组值转换为数组
4.数组实例的entries(),keys(),values()
作用:用于遍历数组,返回一个遍历器对象。可用for...of遍历
- keys()是对键名的遍历,values()是对键值的遍历,entries()是对键值对的遍历