变量的解构赋值
数组的解构赋值
ES 中从数组和对象之中提取数值,对变量进行赋值,这个过程称为解构
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
//如果解构不成功,变量的值等于undefined
let [foo] = [];
console.log(foo); //undefined
1. 对于 Set 解构也可以使用数组的解构赋值
let setData = new Set();
setData.add(1, 2);
setData.add(2);
console.log(setData); //[1,2]
let [x1, x2, x3] = new Set([1, 2]);
console.log(x1, x2, x3); //[1,2,undefined]
2. 事实上,只要某种数据结构具有 Iteator 解构,都可以采用数组的形式进行解构赋值
3. 默认值
let [x = 1, y = 2] = ["第一个值", "第二个值"];
console.log(x, y); //第一个值 第二个值
let [a = 1, b = 2] = [];
console.log(a, b); //1,2
4. ES6 内部使用严格相等运算符,判断一个位置是否有值,所以,如果一个数组的成员不严格等于 undefined,默认值是不会生效的
//数组中成员是null,默认值就不会生效,因为null不等于undefined
let [z = "z", v = "v"] = [undefined, null];
console.log(z, v); // z , null
5. 如果默认值是一个函数表达式,那么这个表达式是惰性求值的,即只有用到的时候,才会求值
function fn() {
console.log("this is a function!!! ");
}
let [x = fn()] = [1];
//因为x能取到值,所以函数fn根本不会执行
console.log(x); //1
上面代码等价于
let x;
if ([1][0] === undefined) {
x = fn();
} else {
x = [1][0];
}
6. 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [a = 10, b = a] = [];
console.log(a, 10);
let [a1 = 30, b1 = a1] = [2];
console.log(a1, b1); //[2]
let [c = 10, d = c] = [undefined, 20];
console.log(c, d); //10,20
对象的解构赋值
与数组不同的是
- 数组解构是根据次序排列的,变量的位置由他的位置决定的
- 对象的属性没有次序,变量名必须与属性同名才能获取到正确的值
const obj = {
name: "Eastboat",
age: 18,
address: "上海市"
};
let { name, age, address: add } = obj;
console.log(name, age, add);
1. 如果变量名和属性名不一致,必须写成这样
let { foo:f } = { foo: "aaa", bar: "bbb" };
console.log(f, bar); // 'aaa','bbb'
//实际说明了对象的解构赋值是以下形式的简写
let {foo:foo,bar:bar}= {foo:"aaa",bar:"bbb}
2. 和数组一样,解构也可用于嵌套结构的对象
let obj = {
parent: "ul",
children: [
"child",
{
name: "li"
}
]
};
let {
parent: a,
children,
children: [b, { name: c }]
} = obj;
console.log(a); /// ul
console.log(children); //[ 'child', { name: 'li' } ]
console.log(b); // child
console.log(c); // li
3. 嵌套赋值
let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: 456 });
console.log(obj, arr); //{ prop: 123 } [ 456 ]
对象的解构赋值可以很方便的把现有的对象的方法赋值到某个变量
let { log, sin, cos } = Math;
字符串的解构赋值
const str = "weclome";
let [a, b, c, d, e] = str;
console.log(a, b, c, d, e); //w e c l o
let { length: len } = str;
console.log(len); //7
数组和布尔值的解构赋值
1. 解构赋值时,如果等号右边是数值和布尔值,则会先转换为对象
let { toString: s } = 123;
console.log(s); //s===Number,prototype.toString
let { toString: s2 } = true;
console.log(s2); ////s===Boolean,prototype.toString
//数组和布尔值的包装对象都有toString属性,因此变量s能取到值
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象,由于 undefined 和 null 无法转换为对象,所以对他们进行解构赋值时都会报错
let { prop: x } = undefined; //TyprError
let { prop: y } = null; //TyprError
函数参数的解构赋值
function add([x, y]) {
return x * y;
}
console.log(add([2, 4])); //8
[
[1, 2],
[3, 4]
].map(([a, b]) => a + b); // [3,7]
- 函数参数的解构也可以使用默认值
function move({ x = 0, y = 0 } = {}) {
return [x, y];
}
console.log(move({ x: 3 })); //[3,0]
console.log(move({})); //[0,0]
console.log(move()); //[0,0]
- 必须为变量指定默认值,而不是为参数指定默认值
function move2({ x, y } = { x: 0, y: 1 }) {
return [x, y];
}
console.log(move2({ x: 3 })); //[3,undefined]
console.log(move2({})); //[undefined,undefined]
- undefined 会触发函数参数的默认值
[1, undefined, 3].map((x = "默认值") => x); // [1,'默认值',3]
圆括号问题
- 不可以使用圆括号的情况
变量声明语句
函数参数
赋值语句的模式
2.可以使用圆括号的情况只有一种:赋值语句的非模式部分可以使用圆括号
[a] = [3](({ p: d } = {}));
变量解构赋值的用途
1.交换变量的值
2.从函数返回多个值
function func() {
return [1, 2, 3];
}
function func2() {
return {
foo: 1,
bar: 2
};
}
let [a, b, c] = func();
let { foo, bar } = func2();
3.函数参数的定义
//解构赋值可以将一组参数与变量名对应起来
function func([x, y, z]) {}
func([1, 2, 3]);
function func2({ x, y, z }) {}
func2({ x: 1, y: 2, z: 3 });
4.提取 JSON 数据(重要)
let jsonDate = {
id: 1,
status: "ok",
data: [1, 2, 3]
};
let { id, status, data: number } = jsonData;
5.函数参数的默认值
6.变量 Map 解构
let map = new Map();
map.set("name", "cc");
map.set("age", 19);
for (let [key, value] of map) {
console.log(key, value);
}
/*
name cc
age 19
*/
//只获取键名
for (let [key] of map) {
console.log(key);
}
//只获取键值
for (let [, value] of map) {
console.log(key);
}
7.输入模块的指定方法
加载模块时,往往需要指定输入的方法,解构赋值使得输入语句非常清晰
const [SourceMapConsumer, SourceNode] = require("source-map");
网友评论