ES6之变量的解构赋值

变量的解构赋值

1. 数组的解构赋值
  • 基本用法

ES6允许写成下面这样

let [a, d, c] = [1, 2, 3]; //按照对应位置对变量赋值

这种写法也叫模式匹配 只要等号两边模式相同(解构成功),左边变量就会被赋予对应的值

let [head, ...tail] = [1, 2, 3, 4]; //...最后值是数组
head // 1
tail // [2, 3, 4]

解构失败,值会等于undefined

let [foo] = [];
let [bar, foo] = [1]; //foo解构不成功

另一种是不完全解构,等号左边的模式只匹配一部分的等号右边的数组(解构依然成功)

let [a, [b], c] = [1, [2, 3], 4]
a // 1
b // 2
...b    b// [2,3] 
c // 4

如果等号右边不是数组(也就是不可遍历的结构)那么将会报错

let [foo] = 1;
let [foo] = false; //不具备Iterator接口
...

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

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

即,只要某种数据结构具有lterator接口,都可以采用数组形式的解构赋值

function *fibs() {  //fibs是一个Generator函数,原生有Iterator接口
    let a =0;
    let b =1;
    while (true) {
        yield a;
        [a,b] = [b, a + b];
    }
}
let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
  • 默认值

解构赋值允许指定默认值

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

let [x = 1, y = 0] = [0, null];
x // 0
y // null
let [x, y = 1] = [1, undefined];
x // 1
y // 1

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

let [x, y = x] = [1, 2];   //x = 1 , y = 2
let [x, y = x] = [1];      //x = 1 , y = 1
let [x = y, y = 1] = [];   //ReferencceError
2. 对象的解构赋值
  • 与数组的不同

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

let { bar, foo } = { foo: "aaa", bar: "bbb" }; //与次序无关,同名赋值

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

 let { foo:baz } = { foo: "aaa", bar: "bbb" };  //baz 'aaa'
 //  属性:变量         //变量赋值

所以可以知道,对象解构其实是以下这种形式:

let { bar:bar, foo:foo } = { foo: "aaa", bar: "bbb" };  //foo 'aaa'
 //  属性:变量                              //变量赋值
let {foo : bar} = { foo: 'bbb'};   
foo // error:foo is not defined
bar // bbb

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

  • 可用于嵌套结构的对象
let obj = {
  p: [
   'hello',
   { y: 'world' } 
   ]
};
let { p: [x, { y }] } = obj;
  • 可用于嵌套赋值
let obj = {};
let arr = [];
({ foo:obj.prop, bar: arr[0] } = { foo: 123, bar: true}) 
obj // {prop:123}
arr // [true]
  • 支持默认值

默认值生效条件:对象的属性值严格等于undefined;解构失败,变量值等于undefined

var {x: y = 3} = {x: 5};
y // 5 
var {x: y = 1} = {};
  • 陷阱

已经声明的变量用于解构赋值,小心使用!
务必把声明变量放在圆括号里赋值

let x;
{x} = {x: 3}; //报错  {x}会被认为是一个代码块
({x} = {x: 3}) // success
  • 数组进行对象解构

因为数组本质是特殊的对象,所以可以对数组进行对象解构

let arr = [1, 2, 3];  //arr 0键对应1  arr.lenght-1就是2键对应3
let {0 : first, [arr.length -1] : last} = arr; 
first // 1
last // 3
3.3 字符串的解构赋值

字符串被转换成一个类似数组的对象

const [a,b,c] = 'dll';
a // 'd'
b // 'l'
c // 'l'

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

let { length : len } = 'hello';
len // 5
3.4 数值和布尔值的解构赋值

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

undefined 和 null 无法转为对象,所以对它们解构赋值时都会报错

3.5 函数参数的解构赋值
  • 对象和数组式传参

表面是数组,传入的那一刻,数组的值就被解构成多个变量

//数组式传参
[[1, 2], [3, 4]].map(([a, b]) => a + b);
// [3, 7]
//对象式传参
function move({x, y} = {}) {
    return [x, y]
}
move({x: 1, y: 2})  // [1,2]

  • 函数传参支持默认值
function move({x = 1, y = 2} = {}) {
    return [x, y]
}
move({})  // [1,2]
move()  // [1,2]
  • 注意写法
function move({x, y} = { x: 1 , y : 2 }) {
    return [x, y]
}
move({})  // [undefined, undefined]
move()  // [1,2]

上面的代码为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到不同结果;undefined就会触发函数参数的默认值。

3.6 圆括号问题

ES6规则:只要有可能导致解构歧义,就不能使用圆括号;

因此在模式中尽量不用圆括号

  • 不能使用圆括号的情况
  1. 变量声明语句
  2. 函数参数
  3. 赋值语句的模式
3.7 用途
  1. 交换变量的值
let x = 1 , y = 2;
[x, y] = [y, x];
  1. 从函数返回多个值

函数要想返回多个值要通过数组或对象;但现在就可以用解构赋值

function exp() {
    return {
        foo: 1,
        bar: 'aaa'
    };
}
let {foo, bar} = exp();
  1. 函数参数的定义

解构赋值可以很方便将一组参数联系起来

fuction f({x, y ,z}) {  ...  }
f({ x: 1, z: 2, y: 0 });
  1. 提取JSON数组
let people = {
    age : 13,
    name : 'dll',
    hope : ['music','pop']
};
let { age, name, hope} =- people;
console.log(age, name, hope);
  1. 函数参数的默认值

指定参数的默认值,避免在函数体内部在写冗长语句(var xxx = xx.xxx || ‘xxx’)

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  //...更多配置
  globale = false
}) {
    // ...你要进行的操作
};
  1. 遍历Map结构

Map结构原生支持Iterator接口,配合变量的解构赋值获取键和键名很方便

var map = new Map();
map.set('first', 'dll');
map.set('second', 'ycy');
for(let [ket, value] of map) {  // let [, value] of map 只要键值
    console.log(key + 'is' + value);
}
  1. 输入模块的指定方法

加载模块时,往往需要指定输入的方法

const { NodeList , getURL } = require('xxx_xx');
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值