1. let & conost
letlet
与var
类似,区别在于let
命令只在代码块内有效;let
有以下特性
- 不存在变量提升
var
会存在变量提升的现象,如下面两段代码
console.log(a)//Reference error
console.log(a);//Undefined
var a=6;
而let
所声明的变量必须在声明之后使用
console.log(a)//Reference error
let a=6;
- 暂时性死区
只要块级作用域存在let
命令,它所声明的变量就"绑定"这个区域,不再受外部影响;在块代码内,如果区块存在let和const命令,则这些命令所声明的变量在声明之前(块内),是不可用的,这被称为暂时性死区
(TDZ)
var a=8;
{
console.log(a)//8
}
var a=8;
{
//TDZ开始
console.log(a)//Reference error
let a=8;
//TDZ结束
}
- 不允许重复声明变量
let
不允许在相同的作用域重复声明同一个变量
{
let a=9;
let a=8;//error
var a=7;//error
}
不容易发现的死区,例如
function bar (x=y,y=3){
console.log(`foo`)
}
constconst
实际上保证的并不是变量的值不该东,而是变量指向的内存地址不改动.对于js的6种基本变量,值就保存在变量指向的地址中,所以不可变动,而对于object
之类的复合型数据变量,只能保证变量指向的地址中保存的对象指针不变动;
同时const
也变量不可提升,存在着暂时性死区
ES6声明变量的6种方法
es5中声明变量只有两种方法,分别是var
和function
,es6除了新添加了const
和let
,还添加了import
和class
关于顶层对象
顶层对象在浏览器中指window
对象,在node中指global
对象,在es5中,顶层对象的属性与全局变量是相同的,在es6中,var
命令和function
命令声明的全局变量依然是顶层对象属性,而let
、const
、class
命令声明的全局变量不是顶层对象属性.
2. 变量解构
数组的解构赋值
- 基本用法
ES6允许按照一定的模式从数组对象中提取值,然后对变量进行赋值,即解构(Destructuring)
let [a,b,c]=[1,2,3]
let [foo,[bar]]=[1,[2]]
只要等号两边的模式相同,左边的变量就会被赋予对应的值,如果未解构成功,则默认为undefined
,只要某种数据结构具有Iterator
接口,都可采用数组形式的解构赋值
- 允许默认值
解构允许指定默认值
let [foo=true]=[]//foo=true
let [x,y='b']=['a']//x='a',y='b'
let [x,y='b']=['a',undefined]//x='a',y='b'
let [x='a']=[null]//x=null
对象的解构赋值
对象与数组的一个重要的不同是变量与属性必须同名才能取得正确的值.
let {bar,foo}={foo:1,bar:2};//foo=1,bar=2
如果变量名和属性名不一致,则必须写成以下这样
let {bar:x,foo}={foo:1,bar:2};//x=2; bar 为reference error
即将:
左边的值赋给了右边的值,上面代码中bar
是模式,x
是变量.
字符串的解构赋值
字符串可以被转换为一个类似数组的对象进行解构赋值
let [a,b,c]='abc'
数值和布尔值解构赋值
解构赋值时,如果等号右边是数值或者布尔值,则会先转为对象
let {toString:s}=1;//s===Number.prototype.toString
函数参数解构
function add([x,y]){
return x+y;
}
3. 函数扩展
函数参数默认值
- 基本用法
ES6之前,不能直接为函数的参数指定默认值,只能在函数体内模拟
function add(x,y){
y=y||2;
return x+y;
}
而在ES6中,允许为函数参数设置默认值
function add(x,y=2){
}
- 参数默认值的位置
在函数调用时,如果函数非尾部的参数设置默认值,这个非尾部参数是无法省略的,需要借助undefined
.如
function add(x=3,y){
return x+y;
}
add(,3)//error
add(undefined,3)
应用,利用参数默认值可以指定某一个参数不得省略,如果省略就抛出一个错误
function throwIfMissing(){
throw new Error(`Missing parameter`)
}
function foo(mustBeProvided=throwIfMissing){
return mustBeProvided;
}
- 函数的length属性
函数的length
属性将返回没有指定默认值的参数的个数,注意,若默认值不是尾参数,则返回第一个默认参数前面参数的个数
(function foo(x,y=2,z){}).length\\1
严格模式
如果函数参数使用了默认值、解构赋值或者扩展运算符,那么函数内部就不能显式设定为严格模式
name属性
函数的name
属性将返回函数的名字,在ES6如果将一个匿名函数赋给一个变量,则改变量会变成这个函数的名字.注意若将一个具名函数赋值给一个变量,则name
属性都返回这个具名函数原本的名字;
const add =()=>{}
const a=add;
a.name;//add
箭头函数
- 基本用法
当箭头后非代码块时候,为一句表达式时,能够隐式地返回计算结果,如
const add=(x,y)=>x+y;
当返回值是一个对象时,需要在对象外添加圆括号,因为大括号会被解析为代码块
const genObj=()=>({a:1,b:2})
当语句多于一句时候,需要添加大括号,并用return
显示返回结果
注意事项
箭头函数内的this对象指向的是其定义时所在的父区域
let a=9; function whichA(){ let a=8; const getA=()=>{ return this.a; } returen getA(); } whichA();//8
- 不可以使用
yield
命令 - 不可以当作构造函数,不可以使用new命令
不可以使用
arguments
对象,其arguments
对象是定义时父区域的arguments
对象.如果使用需要用rest
参数代替function add(){ const sum=()=>{ for (const i in arguments) { console.log(arguments[i]) } } return sum; } add(1,2,3)();//1,2,3 add()(1,2,3);//
5.数组扩展
扩展运算符
- 扩展运算符
扩展运算符...
将一个数组转化为用逗号分隔的参数序列;
...[1,2,3]//1,2,3
apply
方法
apply
方法也能够将一组数组转化为由逗号分割的参数序列
function add (x,y){
return x+y;
}
let ans=add.apply(null,[1,2]);//3
求最大值
//es5;
Math.max.apply(null,[1,2,3]);
//es6;
Math.max(...[1,2,3]);
参考
- 《ES6标准入门》阮一峰