解构赋值

1.数组的解构赋值

允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

1.本质上,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

2.如果解构不成功,变量的值就等于undefined。

3.如果等号右边不是数组(或者不是可遍历的结构),将会报错。

例子:

let [foo, [[bar], baz]] = [1, [[2], 3]];
//foo:1,bar:2, baz:3
let [ , , third] = ["foo", "bar", "baz"];
//third:baz
let [x, , y] = [1, 2, 3];
//x:1, y:3
let [head, ...tail] = [1, 2, 3, 4];
//head:1, tail:[2,3,4]
let [x, y, ...z] = ['a'];
//x:a, y:undefined, z:[]

//报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

不完全解构:即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

例:

let [x, y] = [1, 2, 3];
//x:1, y:2
let [a, [b], d] = [1, [2, 3], 4];
//a:1, b:2, d:4

默认值:解构赋值允许指定默认值。

注意:

1.ES6内部使用严格相等运算符(===)来判断一个位置是否有值,所以,只有当一个数组成员严格等于undefined,默认值才会生效。

2.如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

3.默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

例:

let [foo = true] = [];
//foo:true
let [x, y = 'b'] = ['a'];
//x:a, y:b
let [x, y = 'b'] = ['a', undefined]; 
//x:a, y:b
let [x = 1] = [undefined];
//x:1
let [x = 1] = [null];
//x:null

//引用其他变量
let [x = 1, y = x] = [];
//x:1, y:1
let [x = 1, y = x] = [2]; 
//x:2, y:2
let [x = 1, y = x] = [1, 2]; 
//x:1, y:2
let [x = y, y = 1] = [];
//报错

2.对象的解构赋值

数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let { bar, foo } = { foo: "aaa", bar: "bbb" };
//bar:bbb, foo:aaa
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;
//first是匹配的模式,f才是变量。真正被赋值的是变量f,而不是模式first。 f:hello, l:world

解构嵌套结构的对象

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
//x:Hello, y:World

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;
//p:['Hello',{y: 'World' }],  x:Hello, y:World

const node = {
  loc: {
    start: {
      line: 1,
      column: 5
    }
  }
};

let { loc, loc: { start }, loc: { start: { line }} } = node;
//line:1,
//start: { line: 1, column: 5}
//loc:{start: { line: 1, column: 5} }
//注意:在最后一次对line属性的解构赋值之中,只有line是变量

let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
//obj:{prop:123}, arr:[true]

默认值(同数组):

如果解构模式是嵌套的对象,而且子对象所在的父元素不存在,将会报错

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 {x = 3} = {x: undefined};
//x:3
var {x = 3} = {x: null};
//x:null
let {foo} = {bar: 'baz'};
//foo:undefined
let {foo: {bar}} = {baz: 'baz'};
//报错

如果要将一个已经声明的变量用于解构赋值,外面要加一个圆括号。

let x;
{x} = {x: 1};
//报错,JavaScript会将{x}理解成一个代码块,从而发生语法错误

let x;
({x} = {x: 1});

3.字符串的解构赋值

字符串解构赋值时,字符串被转换成一个类似数组的对象。

还可以对length属性进行解构赋值。

const [a, b, c, d, e] = 'hello';
//a:h, b:e, c:l, d:l, e:o
let {length : len} = 'hello';
//len:5

4.数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

如果是undefined和null无法转为对象,在对他们进行解构赋值会报错。

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

5.函数参数的解构赋值

function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

参考:《es6标准入门》

 

原文地址:https://www.cnblogs.com/zsj-02-14/p/10209192.html