es6之解构赋值

解构赋值语法是一个 Javascript 表达式,这使得可以将值从数组或属性从对象提取到不同的变量中。
解构赋值的分类:数组解构赋值、对象解构赋值 、字符串解构赋值、布尔值解构赋值、 函数解构赋值、数值解构赋值。

1.数组解构赋值

等号右边不是数组的解构
let [a]=1;
let [a]=false;
let [a]=NaN;
let [a]=undefined;
let [a]=null;
let [a]={};

上面的表达式会报错,因为右边的值转化成对象后不具备可遍历的结构(前五个表达式),或者本身就不具备可遍历的结构(最后一个表达式)。

变量声明并赋值时的解构
let [a,b]=[1,2];
console.log(a,b);  // 1 2
变量先声明后赋值时的解构

通过解构分离变量的声明,可以为一个变量赋值。

let a,b;
[a,b]=[1,2];
console.log(a,b);  // 1 2
有默认值时的解构
let a,b;
[a=7,b=1]=[1];
console.log(a,b);  // 1 1

如果一个数组的成员不严格等于undefined,默认值是不会生效的。

var [x=1] = [undefined]
console.log(x);  // 1;
var [y=1] = [null];
console.log(y);  // null

上面代码中,null 不严格等于 undefined,所以默认值不会生效。
默认值也可以是个表达式。

function a(){
    console.log("aaa");
}
var [x=a()] = [1];
console.log(x);  // 1

x可以取到值,所以a()不会执行。
默认值也可以是变量,但是该变量必须已经声明。

let [x=1,y=x] = [2];
console.log(x,y);  // 2 2
let [a=b,b=1] = [2];
// ReferenceError

上述后面一个表达式报错,因为a用到默认值b时b还没声明。

不完全解构

即等号左边的模式只匹配等号右边数组的一部分。

let a,b;
[a,b]=[1,5,9];
console.log(a,b);  // 1 5

这时候也是可以解构成功的。

左边的数组长度大于右边的数组长度时的结构
let [x] = [];
console.log(x); // undefined
let [a,b] = [5];
console.log(a,b);  // 5 undefined

此时x和b都结构不成功,值都会等于undefined。

忽略某些返回值
function f(){
    return [1,2,3,4,5]
}
let a,b,c;
[a,,,b]=f();
console.log(a,b);  // 1 4
将剩余数组赋值给一个变量

当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。

let a,b,rest;
[a,b,...rest] = [1,2,3,4,5,6]
console.log(a,b,rest);  //1 2 [3,4,5,6]

右边数组长度不够时:

let a,rest;
[a,...rest] = [1]
console.log(a,rest);  // 1 []

此时rest会返回空数组,这点需要额外注意。
注意:如果剩余元素右侧有一个逗号,会抛出SyntaxError,因为剩余元素必须是数组的最后一个元素。

2.对象解构赋值

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

var {name,age}={name:"张三",age:45}
console.log(name,age);  // "张三" 45
var {city} = {name:"张三"}
console.log(city);  // undefined

上面代码city与右边的属性名不相同,导致取不到值,所以等于undefined。

基本赋值
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
无声明赋值

通过解构可以无需声明来赋值一个变量。

var a, b;
({a, b} = {a: 1, b: 2});

赋值语句周围的( .. ) 是使用对象字面解构赋值时不需要声明的语法。{a, b} = {a: 1, b: 2}不是有效的独立语法,因为左边的{a, b}被认为是一个块而不是对象字面量。然而,({a, b} = {a: 1, b: 2})是有效的,正如 var {a, b} = {a: 1, b: 2}
注意:你的( .. ) 表达式需要一个分号在它前面,否则它也许会被当成上一行中的函数来执行。

解构嵌套对象

解构方式跟对象取值类似。

var obj={
    p:[
        "world",
        {x:"hello"}
    ]
}
var {p:[text,{text2}]} = obj;
console.log(text,text2);  // "world" "hello"

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

var {foo:baz} = {baz:'baz'} //报错

上面的代码中,等号左边对象的foo属性对应一个子对象。该子对象的baz属性解构时会报错,因为foo这时等于undefined,再取子属性就会报错。

3.字符串解构赋值

字符串也是可以解构赋值的。

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

上面的代码,字符串被转换成了一个类似数组的对象.

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

类似数组的对象有length属性,所以可以对这个属性解构赋值。

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

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

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。
解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

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

5.函数的解构赋值

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

function add([x, y]){
  return x + y;
}
add([1, 2]) // 3

上面代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到的参数就是x和y。

6.解构赋值的用途

  1. 变量交换
  2. 接受函数返回值
  3. 选择性接受返回值
  4. 当不知道返回值数组长度时,取所需要的的数值。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值