ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
一.对象的解构赋值
1.基本写法
-
基本写法
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }; foo // "aaa" bar // "bbb"
2.特点
-
① 对象属性赋值是按照属性名匹配的,和属性顺序无关。
let { bar, foo } = { foo: 'aaa', bar: 'bbb' }; foo // "aaa" bar // "bbb"
-
② 对象解构无相应属性,赋值为
undefined
let {foo} = {bar: 'baz'}; foo // undefined
-
③ 对象的解构赋值可以取到继承的属性
const obj1 = {}; const obj2 = { foo: 'bar' }; Object.setPrototypeOf(obj1, obj2); const { foo } = obj1; foo // "bar"
-
④ 与数组一样,解构也可以用于嵌套结构的对象。
//一.嵌套结构 let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p: [x, { y }] } = obj; x // "Hello" y // "World" //二.这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样 let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p, p: [x, { y }] } = obj; x // "Hello" y // "World" p // ["Hello", {y: "World"}] //三.关于嵌套解构更多范例: //下面代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值。注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。 const node = { loc: { start: { line: 1, column: 5 } } }; let { loc, loc: { start }, loc: { start: { line }} } = node; line // 1 loc // Object {start: Object} start // Object {line: 1, column: 5} //嵌套赋值的例子 let obj = {}; let arr = []; ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true }); obj // {prop:123} arr // [true] // 报错 //下面代码中,等号左边对象的foo属性,对应一个子对象。该子对象的bar属性,解构时会报错。原因很简单,因为foo这时等于undefined,再取子属性就会报错。 let {foo: {bar}} = {baz: 'baz'};
3.对象解构赋值的本质
-
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
//变量名与属性名处理 let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; baz // "aaa" let obj = { first: 'hello', last: 'world' }; let { first: f, last: l } = obj; f // 'hello' l // 'world' //如下:foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。 let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; baz // "aaa" foo // error: foo is not defined
4.对象解构赋值的使用
-
① 将现有变量赋值给我们定义的同名变量。
// 例一 将Math对象的对数、正弦、余弦三个方法,赋值到对应的变量上 let { log, sin, cos } = Math; // 例二 console.log赋值到log变量 const { log } = console; log('hello') // hello
5.默认值
-
对象的解构也可以指定默认值。
var {x = 3} = {}; x // 3 var {x, y = 5} = {x: 1}; x // 1 y // 5 var {x: y = 3} = {}; y // 3 var {x: y = 3} = {x: 5}; y // 5 var { message: msg = 'Something went wrong' } = {}; msg // "Something went wrong"
-
默认值生效的条件是,对象的属性值严格等于undefined。
var {x = 3} = {x: undefined}; x // 3 var {x = 3} = {x: null}; x // null
6.解决歧义
-
如果要将一个已经声明的变量用于解构赋值,可能会出现歧义。
// 一 错误的写法:因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。 let x; {x} = {x: 1}; // SyntaxError: syntax error //二 将对象放在一个圆括号里面,解释为对象 // 正确的写法 let x; ({x} = {x: 1});
-
解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。
({} = [true, false]); ({} = 'abc'); ({} = []);
-
由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3]; let {0 : first, [arr.length - 1] : last} = arr; first // 1 last // 3
来源:CSDN
作者:张大仙是个妖怪
链接:https://blog.csdn.net/NDKHBWH/article/details/103746221