变量的解构赋值 - 对象篇
2020-10-20 本文已影响0人
坏丶毛病
上次讲了数组的解构赋值,这次来看下对象的解构赋值
对象的解构和数组不同之处在于,数组的元素是按次序排列的,变量的取值是由位置决定的,而对象的属性没有次序,变量必须与属性同名才能取到正确的值
let { bar, foo } = { foo: 'aaa', bar: 'bbb'};
console.log(foo, bar); // aaa, bbb
let { baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz); // undefined
好了,话不多说,来看一些demo吧
// 如果变量名与属性名不一致,必须写成下面这样
let { a: c } = { a: 'aaa', b: 'bbb'};
console.log(c); // aaa
let obj = { first: 'hello', last: 'world'};
let { first: f, last: l } = obj;
console.log(f, l); // hello, world
// 实际上说明,对象的解构赋值是下面形式的简写
// let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb'};
// 也就是说,对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者
// 下面的例子说明:d是匹配的模式,e才是变量,真正被赋值的是变量e,而不是模式d
let { d: e } = { d: 'aaa', bar: 'bbb'}
console.log(e); // aaa
// console.log(d); // d is not defined
// 与数组一样,解构也可以用于嵌套的对象
let obj2 = {
p: [
'Hello',
{ y: 'World'}
]
};
let { p: [x, { y }] } = obj2;
console.log(x, y); // Hello, World
// 这里p只是作为匹配模式,不是变量,如果p也要作为变量赋值,可以写成如下这样
let { p, p: [g, { h }] } = obj2;
console.log(g, h); // Hello, World
console.log(p); // ['Hello', { y: 'World'}]
// 以下代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值,需要注意,最后一次对line属性的解构赋值中,只有line是变量,loc和start都是模式
var node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
var { loc, loc: { start }, loc: { start: { line }} } = node;
console.log(loc); // {start: { line: 1, column: 5 } } 对象Object
console.log(start); // { line: 1, column: 5 } 对象Object
console.log(line); // 1
// 嵌套赋值的例子:
let obj3 = {};
let arr = [];
({ foo: obj3.prop, bar: arr[0] } = { foo: 123, bar: true})
console.log(obj3); // { prop: 123}
console.log(arr); // [true]
// 对象的解构赋值也可以指定默认值
var { i = 3 } = {};
console.log(i); // 3
var { j, k = 5 } = { j: 1 };
console.log(j, k); // 1, 5
var { m: n = 3 } = {}
console.log(n); // 3
var { o: q = 3 } = { o: 5 };
console.log(q); // 5
var { message: msg = 'Something went wrong' } = {};
console.log(msg); // 'Something went wrong'
// 默认值生效的条件是:对象的属性值严格等于undefined(===)
var { r = 3 } = { r: undefined };
console.log(r); // 3
var { s = 3 } = { s: null };
console.log(s); // null:不严格等于undefined,所以默认值不会生效
// 如果解构失败,变量的值等于undefined
let { name } = { age: 18 };
console.log(name); // undefined
// 如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么会报错
let { foo: { sex }} = { baz: 'baz'}; // 报错:foo在对象中取不到,此时等于undefined,再取子属性就会报错
// 上述代码类似于下面这样:
let _temp = { baz: 'baz' };
console.log(_tmp.foo.sex);
// 如果要将一个已经声明的变量进行解构赋值,必须注意
/*
错误的写法:(报错)
let x;
{ x } = { x: 1 };
正确的写法:(加个括号,只有不将大括号放在行首,从而避免js将其解释为代码块)
let x;
({ x } = { x: 1});
*/
// 解构赋值允许等号左边的模式之中不放置任何变量名,因此可以写成很多古怪的赋值表达式,虽然有些毫无意义,但是语法都是合法的,可以正常执行
({} = [true, false]);
({} = 'abc');
({} = []);
// 对象的解构赋值可以很方便的将现有对象的方法赋值到某个变量
// 例如:将Math对象的对数、正弦、余弦三个方法赋值到对应变量
let { log, sin, cos } = Math;
// 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构赋值
let arr2 = [1, 2, 3];
let { 0: one, [arr2.length - 1]: two} = arr2;
console.log(one); // 1
console.log(two); // 3
以上,就是对象的解构赋值。
数组解构赋值:数组的解构赋值
变量的解构赋值 - 字符串、数值、布尔值、函数参数:变量的解构赋值 - 字符串、数值、布尔值、函数参数
如有问题,请指出,接受批评。