过一遍ES6(三)--- 对象的解构赋值

解构:ES6按照一定的模式,从数组和对象中提取值,对变量进行赋值
对象的结构赋值与数组结构赋值的不同之处:数组元素时按次序排列的,变量的取值由它的位置决定;对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

对象的结构赋值

1 形式

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

若变量名与属性名不一致:

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'

所以对象的结构赋值是 let { foo: foo, bar: bar } = { foo: “aaa”, bar: “bbb” }
也就是说对象的结构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者而不是前者

//此代码中,foo是匹配模式,baz 是变量,真正赋值的是变量baz,而不是模式foo
let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

2 结构嵌套结构

// 此时p是模式,不是变量,因此不会被赋值
let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
// 如果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是变量,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]

3 指定默认值
默认值生效的条件是: 对象的属性值严格等于undefined

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"

var {x = 3} = {x: undefined};
x // 3

// 由于null与undefined不严格相等,所以默认值时无效的
var {x = 3} = {x: null};
x // null

4、解构赋值过程中出现报错的情况
① 解构失败,变量的值为undefined

let {foo} = {bar: 'baz'};
foo // undefined

② 解构模式是嵌套的对象,而且子对象所在的父属性不存在,将会报错

// 报错
// 此时foo为undefined,再取子属性就会报错
let {foo: {bar}} = {baz: 'baz'};

③ 将一个已经声明的变量用于解构赋值的错误写法

// 错误的写法
// javascript引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题
let x;
{x} = {x: 1};
// SyntaxError: syntax error

// 正确的写法
let x;
({x} = {x: 1});

5 解构赋值允许等号左边的模式之中,不放置任何变量名。

({} = [true, false]);
({} = 'abc');
({} = []);
// 代码虽古怪,表达式毫无意义,但是语法是合法的,可以执行

6 将现有对象的方法通过解构赋值到某个变量

// 将Math对象中的方法赋值给相对应的变量
let { log, sin, cos } = Math;

7 对数组进行对象属性的解构
数组是特殊的对象,因此可以对数组进行对象属性的解构

let arr = [1, 2, 3];
let {0 : first, [arr.length - 1] : last} = arr;
first // 1
last // 3

猜你喜欢

转载自blog.csdn.net/hhf235678/article/details/82354371