解构(Destructuring)赋值

在es5中我们进行相关赋值的时候,只能一个一个进行赋值,使用逗号的进行赋值也只是最右边的赋值 才生效。在es6中出现了赋值解构,分两种情况一个是数组解构,一个是对象解构赋值。这么好用的方法给我带来很多便利。

在解构中有以下两部分参与:

  • 解构的源:解构赋值表达式的右边部分
  • 解构的目标:解构赋值表达式的左边部分

数组解构

数组解构的几种类型:

//模式匹配 只要等号两边的模式相同,左边的变量就会被赋予对应的值
let [a, b, c] = [1, 2, 3];   //可以从数组中提取值,按照对应位置,对变量赋值
// a = 1
// b = 2
// c = 3

//嵌套的数组
let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3

// 左右两边的参数可以不对等,如果等号左边没有全部匹配右边也是可以结构成功的
let [a, , b] = [1, 2, 3];
// a = 1
// b = 3

// 下面这个打印b的值结果为undefined
let [a, b, c] = [1, , 3];

// 不完全解构
let [a, b] = [1, 2, 3];  // a = 1, b = 2
let [a, [b], d] = [1, [2, 3], 4];    // a = 1 b = 2 c = 3

//剩余运算符
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]

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

let [foo] = [];
let [bar, foo] = [1];

如上面不完全解构中,b的值为undefined,表示解构失败。

如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错。

let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
//TypeError: {} is not iterable 

上面的语句都会报错,因为等号右边的值,要么转为对象以后不具备 Iterator 接口(前五个表达式),要么本身就不具备 Iterator 接口(最后一个表达式)。

对于 Set 结构,也可以使用数组的解构赋值。

let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"

对象解构

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

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

当没有这个值时,会返回undefined。

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

对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。

// 例一
let { log, sin, cos } = Math;

// 例二
const { log } = console;
log('hello') // hello

如果变量名和属性名不一致,要写成这样:

let { foo: foo1, bar: bar1 } = { foo: 'aaa', bar: 'bbb' };
foo1     // 'aaa'
bar1     // 'bbb'

foo        // ReferenceError: foo is not defined

也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

对象嵌套结构:

let node = {
    type: "Identifier",
    name: "foo",
    loc: {
        start: {
            line: 1,
            column: 1
        },
        end: {
            line: 1,
            column: 4
        }
    }
};
let { loc: { start } } = node;
console.log(start.line); // 1
console.log(start.column); // 1

对象的解构也有默认值:

默认值生效的条件是,对象的属性值严格等于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

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

注意:

// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error

上面代码的写法会报错,因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

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

上面代码将整个解构赋值语句,放在一个圆括号里面,就可以正确执行。

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5

函数参数解构

函数的参数也可以使用解构赋值。

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3

//或者
function query({name, age}){
  // doSomething
}

详细请查看ES6 解构教程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值