解构
对象解构
let node = {
type: "id",
name: "shaun"
};
let {type, name} = node;
console.log(type); // "id"
console.log(name); // "shaun"
- 不要忘记初始化程序(等号右侧的值)
- 解构赋值表达式(=右侧的表达式)如果为null或undefined会抛出错误
- 语法错误
// 解构
var {type, name}; // uncaught SyntaxError
let {type, name}; // uncaught SyntaxError
const {type, name}; // uncaught SyntaxError
// 声明
const name; // uncaught SyntaxError
let name; // undefined
解构赋值
- 变量赋值时解构赋值
* 一定要用小括号将解构赋值语句包裹
- js将一对开放的花括号视作一个代码块
- 语法规定,代码块不允许出现在赋值语句左侧
- 添加小括号可以将块语句转化为表达式,实现解构赋值
let node = {
type: "id",
name: "shaun"
},
type = "cls",
name = "david";
// 解构赋值(注意括号)
({type, name} = node);
// 变量的值被修改
console.log(type); // "id"
console.log(name); // "shaun"
let node = {
type: "id",
name: "shaun"
},
type = "cls",
name = "david";
// 函数被调用时,传入的value等同为'info({type, name} = node)'中=右侧的值,即node
function info(value) {
console.log(value === node); // true
}
// 触发解构赋值
info({type, name} = node);
// 变量的值被修改
console.log(type); // "id"
console.log(name); // "shaun"
默认值
- 若指定的局部变量名在对象中不存在,则会被赋值undefined
let node = {
type: "id",
name: "shaun"
};
let {type, name, value} = node;
console.log(type); // "id"
console.log(name); // "shaun"
console.log(value); // "undefined"
let node = {
type: "id",
name: "shaun"
};
let {type, name, value = true} = node;
console.log(type); // "id"
console.log(name); // "shaun"
console.log(value); // true
为非同名局部变量赋值
let node = {
type: "id",
name: "shaun"
};
let {type: localType, name: localname} = node;
console.log(localType); // "id"
console.log(localname); // "shaun"
let node = {
type: "id"
};
let {type: localType, name: localname = "bar"} = node;
console.log(localType); // "id"
console.log(localname); // "bar"
嵌套对象解构
- 将对象拆解以获取想要的信息
- 解构模式中用了花括号,意义是:
- 冒号前的标识符都代表在对象中检索的位置
- 冒号后为被赋值的变量名
- 若冒号后为花括号,意味着要赋予的最终值嵌套在对象内部更深的层级中
let node = {
type: "id",
name: "shaun",
loc: {
start:{
line: 1,
column: 2
},
end: {
line: 3,
column: 6
}
}
};
let {loc: {start}} = node;
console.log(start.line); // "1"
console.log(start.column); // "2"
let node = {
type: "id",
name: "shaun",
loc: {
start:{
line: 1,
column: 2
},
end: {
line: 3,
column: 6
}
}
};
// 提取node.loc.start
// node.loc.start的值被储存在新的局部变量localStart中
let {loc: {start: localStart}} = node;
// 未声明任何变量,没有任何作用
// 不会声明任何绑定
// 未来可能会被废弃的功能
// 可以用默认值来完成目的:let {loc: {} = {a:true}} = node;
let {loc: {}} = node;
console.log(localStart.line); // "1"
console.log(localStart.column); // "2"
数组解构
- 使用数组字面量
- 解构操作全部在数组内部完成
- 不会像对象解构那样运用对象的命名属性
let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
// 数组解构中通过值在数组中的位置进行选取,将其储存在任意变量中
// 未显式声明的元素都会直接被忽略(如"blue")
// 结构过程中,原数组不发生任何变化
console.log(firstColor); // "red"
console.log(secondColor); // "green"
let colors = [ "red", "green", "blue" ];
// 逗号只是占位符
let [ , , thirdColor ] = colors;
// 数组解构中通过值在数组中的位置进行选取,将其储存在任意变量中
// 未显式声明的元素都会直接被忽略(如"blue")
// 结构过程中,原数组不发生任何变化
console.log(thirdColor); // "blue"
- 与对象解构一样,通过var, let, const声明数组解构的绑定时,必须提供初始化程序(=右侧)
解构赋值
let colors = [ "red", "green", "blue" ],
firstColor = "gray",
secondColor = "black";
[ firstColor, secondColor ] = colors;
// 数组解构中通过值在数组中的位置进行选取,将其储存在任意变量中
// 未显式声明的元素都会直接被忽略(如"blue")
// 结构过程中,原数组不发生任何变化
console.log(firstColor); // "red"
console.log(secondColor); // "green"
let a =1,
b = 2,
tmp;
tmp = a;
a = b;
b = tmp;
console.log(a); // 2
console.log(b); // 1
+ ES6可以直接用解构
let a =1,
b = 2;
// 左侧是数组解构模式
// 右侧是一个为交换临时创建的数组字面量
// 执行过程中是先解构临时数组,将b, a的值复制到左侧的前两个位置
// 结果就是交换了他们的值
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
默认值
- 当指定位置的属性不存在或者其值为undefined,要用默认值
let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
嵌套数组解构
- 在原有数组模式中插入另一个数组模式,即可解构深入到下一个层级
let colors = [ "red", ["green", "blue"] ];
// secondColor变量取["green", "blue"]的第一个位置的值
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
不定元素
- 数组中可以通过不定元素(...rest)将数组中其余元素赋值给一个特定的变量
- 不过不定元素必须为最后一个条目
- 在其后面继续添加逗号,会报错
let colors = [ "red", "green", "blue" ];
let [ firstColor, ...restColor ] = colors;
console.log(firstColor); // "red"
console.log(restColor.length); // 2
console.log(restColor[0]); // "green"
console.log(restColor[1]); // "blue"
let colors = [ "red", "green", "blue" ];
let clonedColors = colors.concat();
console.log(clonedColors); // "[red, green, blue]"
+ ES6可以直接用解构
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors] = colors;
console.log(clonedColors); // "[red, green, blue]"
混合解构
- 可以混合使用对象和数组的解构来创建更复杂的表达式,提取你想要的信息
- 此种方法对从json中提取数据非常有用,不需要再遍历整个json数据
- 下面代码中
let { loc: {start}, range: [startIndex] } = node;
的'loc:'和'range:'只是代表他们在node中所处的位置(即该对象的属性)
let node = {
type: "id",
name: "shaun",
loc: {
start: {
line: 1,
column: 2
}
},
range: [0, 3]
};
let { loc: {start}, range: [startIndex] } = node;
console.log(start.line); // 1
console.log(start.column); // 2
console.log(startIndex); // 0
解构参数
- 解构参数支持所有解构特性:默认值,混合对象和数组的结构模式,以及非同名变量存储信息等
- 解构可以用在函数传递参数的过程中
function setCookie(name, value, options) {
options = options || {};
let secure = options.secure,
path = options.path,
domain = options.domain,
expires = options.expires;
// to do...
}
// 第三个参数自动映射到options参数内
setCookie("type", "js", {secure: true, expires: 6000});
+ 解构模式:
function setCookie(name, value, {secure, path, domain, expires}) {
// to do...
}
setCookie("type", "js", {secure: true, expires: 6000});
必须传值的解构参数
- 以上代码第三项为解构参数,如果调用函数时不提供被解构的参数,会报错,如:
function setCookie(name, value, {secure, path, domain, expires}) {
// to do...
}
setCookie("type", "js"); // 报错
function setCookie(name, value, {secure, path, domain, expires} = {}) {
// to do...
}
setCookie("type", "js"); // 正常
解构参数的默认值
function setCookie(name, value,
{
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
} = {
// 以下为默认参数
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
}
) {
// to do...
}
setCookie("type", "js"); // 正常
// 修改参数便利,自动同步,还可以直接用这个对象来为每一个绑定设置默认参数
const setCookieDefaults = {
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
}
function setCookie(name, value,
{
secure = setCookieDefaults.secure,
path = setCookieDefaults.path,
domain = setCookieDefaults.domain,
expires = setCookieDefaults.expires
} = setCookieDefaults
) {
// to do...
}
setCookie("type", "js"); // 正常