ES6
解构
对象解构
// 例1:对象解构
let node = {
type:"id",
name:"foo"
};
let {type,name} = node;
console.log(type);
console.log(name);
// 例2: 语法错误
let {name,type};
// 例3: 在变量定义之后用解构语法赋值
let node = {
type:"id",
name:"foo"
},
type = "name",
name = "xlx";
({type,name} = node);
// 例4: 函数传递参数时使用解构赋值
let node = {
type:"id",
name:"foo"
},
type = "name",
name = "xlx";
function outputInfo(value){
console.log(value === node);//true
}
outputInfo({type,name} = node);
// 例5: 变量在对象中不存在,这个变量会被赋值undefined
let node = {
type:"id",
name:"foo"
};
let {type,name,value} = node;
console.log(value);//undefined
// 例6: 防止例5的情况出现可以为可能不存在的变量设置默认值
let node = {
type:"id",
name:"foo"
};
let {type,name,value=true} = node;
// 例7: 为非同名的变量赋值(解构赋值设置变量别名)
let node = {
type:"id",
name:"foo"
};
let {type:localType,name:localName} = node;
console.log(localType);//打印id,此时type对应被解构对象内的type,解构之后的值赋值给变量localType
// 例8: 为非同名变量赋值时设置默认值(类似例6)
let node = {
type:"id"
};
let {type:localType,name:localName="xlx"} = node;
// 例9: 嵌套对象解构
let node = {
type:"id",
name:"foo",
loc:{
start:{
line:1
column:1
},
end:{
line:1,
column:4
}
}
};
let {loc:{start}} = node;
console.log(start.line);//1
console.log(start.column);//1
// 例10: 嵌套对象解构时设置非同名变量
let node = {
type:"id",
name:"foo",
loc:{
start:{
line:1
column:1
},
end:{
line:1,
column:4
}
}
};
let {loc:{start:localStart}} = node;
console.log(localStart.line);//1
console.log(localStart.column);//1
注意:
- 使用
var/let/const声明解构变量时需要初始化变量!(例2) - 要用一对小括号包裹解构辅助语句,因为
JavaScript引擎将一对开放的花括号视为一个代码块,而语法规定:代码块语句不允许出现在解构赋值语句左侧!.(例3) - 解构赋值表达式
=右侧如果为null或者undefined,会抛异常! - 设置变量默认值时只有当对象中没有该属性或者该属性的值为
undefined时才有效!(例6) - 使用嵌套解构时,形如
let {loc:{}} = node;的表达式虽然在语法中是合法的,但是是无效的,这条语句什么也没做!
数组解构
// 例1: 数组解构
let colors = ["red","green","blue"];
let [firstColor,secondColor] = colors;
// 例2: 省略元素,按需提取
let colors = ["red","green","blue"];
let [ , , thirdColor] = colors;
// 例3: 解构赋值
let colors = ["red","green","blue"],
firstColor = "black",
secondColor = "purple";
[firstColor,secondColor] = colors;
// 例4: ES5中交换变量的值需要定义中间量,但是ES6中可以用解构方式实现
let a = 1,b = 2;
[a,b] = [b,a];
// 例5: 默认值
let colors = ["red"];
let [firstColor,secondColor="green"] = colors;
// 例6: 嵌套解构
let colors = ["red",["green","lightgreen"],"blue"];
let [firstColor,[secondColor]] = colors;
// 例7: 不定元素,通过不定元素把数组中剩余的值全部赋给一个变量
let colors = ["red","green","blue"];
let [firstColor, ...restColors] = colors;
注意:
- 数组结构是根据变量在数组中的位置进行选取,可以将其存储在任意变量中,未显式声明的变量都会被忽略,数组本身不会发生变化!
- 使用
var/let/const声明解构变量时需要初始化变量!(与对象解构类似) - 与对象解构不同,数组解构在解构赋值时不需要用小括号包裹表达式!(例3,类比对象解构的例3)
- 解构赋值表达式
=右侧如果为null或者undefined,会抛异常!(与对象解构相似)
克隆数组
数组解构中的不定元素可以用来实现数组克隆.
在ES5中的数组克隆的实现,一般使用concat().这个方法的设计初衷是连接两个数组,只是调用时不传参数,就会返回当前数组的副本.ES6中的实现如下:
let colors = ["red","green","blue"];
let [...clonedColors] = colors;
解构参数
解构参数使得参数的传递变得更清晰,并且能节省代码.
// 解构参数之前
function setCookie(name,value,options){
options = options || {};
let secure = options.secure,
path = options.path,
domain = options.domain,
expire = options.expire;
// 设置cookie代码
......
}
setCookie("type","js",{
secure:true,
expire:60000
});
// 解构参数之后
function setCookie(name,value,{secure,path,domain,expire}){
// 设置cookie代码
......
}
setCookie("type","js",{
secure:true,
expire:60000
});
注意: 解构参数有一个非常需要注意的地方,在上面的例子中,如果调用setCookie()时,不传入第三个被解构的参数,相当于在操作解构时,=右边是undefined.根据之前讲过的,此时程序会抛出异常.所以参数解构时不能不传被解构参数.
但是,当被解构的参数需要被设置为可选参数时,应该怎么做?
解构参数的默认值
上面提到的问题,可以用设置参数默认值来解决.
// 被解构的参数可能不存在的情况
function setCookie(name,value,{secure,path,domain,expire}={}){
// 业务代码
......
}
// 被解构参数存在,但内部属性可能不存在的情况
function setCookie(name,value,{
secure = false,
path = "/",
domain = "example.com",
expire = 60000}){
// 业务代码
......
}
// 被解构参数和内部属性都可能不存在的情况
function setCookie(name,value,{
secure = false,
path = "/",
domain = "example.com",
expire = 60000} = {
secure = false,
path = "/",
domain = "example.com",
expire = 60000}){
// 业务代码
......
}
虽然第三个例子中,函数边变得很完整,但是这时候代码也出现了一定量的冗余,可读性也变差.这时候可以将默认值提取到一个独立对象中,并且使用该对象作为解构和默认参数的一部分,从而消除冗余.