ES6 —(解构赋值)

1、数组解构赋值

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

let [a, b, c] = [1, 2, 3];
//a => 1, b => 2, c=> 3;

  本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。数组的元素是按次序排列的,变量的取值由它的位置决定。

注意
  (1)等号右边必须是可遍历的,即具备 Iterator 接口。若等号右边不可遍历将会报错。如:

//以下代码会报错
let [foo1] = 1;
let [foo2] = false;
let [foo3] = NaN;
let [foo4] = undefined;
let [foo5] = null;
let [foo6] = {};

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


  (2)解构失败,即等号右边少值。如果解构失败,变量的值就等于 undefined 。不完全解构,即等号左边少值。此时,忽略等号右边多余值。


  (3)解构不等同于直接赋值。

//正常赋值
let a = 0;
let b = 1;
a = b;
b = a + b;
console.log(a+" "+ b); // a => 1, b => 2

//解构
let a = 0;
let b = 1;
[a, b] = [b, a + b];
console.log(a+" "+ b); // a => 1, b => 1

  (4)解构赋值允许指定默认值。但在 ES6 内部使用严格相等运算符( === )来判断一个位置是否有值。所以,如果一个数组成员不严格等于 undefined ,默认值是不会生效的。如:

let [a = 'a', b = 'b', c = a , d = a] = [1, undefined, null, ,2];
console.log(a+" "+ b + " " + c + " " + d);
// a => 1, b => b, c => null, d => 1

因为 null 不严格等于 undefined ,所以 c d 的默认值不会生效,而是分别被赋予了 null a 的值 1 。并且默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

2、对象的解构赋值

  对象的数学没有次序,变量必须与属性同名,才能取到正确的值。

let {a, b, c ,d} = {a: 1, c: "c", b: "b" };
console.log(a+" "+ b + " " + c + " " + d);
//a => 1, b => b, c => c, d =>undefined

上述例子中, a 在左右两边的次序相同, b c 在左右两边的次序不一致,但是对取值完全没有影响。由于右边没有与 d 对应的同名属性,导致取不到值,最后等于 undefined 。

注意

  (1)对象的解构赋值的内部机制,是先找到同名属性,然后再赋值给对应的变量。

let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

上述代码中, foo 是模式匹配, baz 才是变量。真正被赋值的是变量 baz ,而不是模式 foo 。也就是说真正被赋值的是后者,而不是前者。

  当变量名与属性名同名是可省略变量名,但当变量名与属性名不一致时,必须写成 { foo : baz} 格式。

  (2)对象解构与数组一样,可以使用嵌套结构,但是如果右边子对象所在的父附属性不存在,将会报错。因为等号左边对象的 foo 属性对应一个子对象 bar ,但是 foo 这时等于 undefined ,再取子属性将会报错;

let {foo: {bar}} = {bar:'bar'}; //报错Cannot match against 'undefined' or 'null'
let {bar} = {foo: {bar:'bar'}}; //bar => undefined

可以使用默认值,默认值生效的条件是对象的属性值严格等于 undefined

  (3)若将一个已声明的变量用于解构赋值,必须要将整个解构赋值语句放在一个圆括号里,否则将报错。

let x;
({x} = {x : 1}); // 正确
{x} = {x : 1}; // 报错, Unexpected token =

这是因为, js 引擎会将 {x} 理解成一个代码块,从而产生的语法错误。

3、字符串对象的解构赋值

  字符串解构赋值,是将字符串转换成了一个类似数组的对象,类似数组的对象都有一个 length 属性,因此还可以对这个属性解构赋值。

let [a , b, c] = 'get';// a => g, b => e, c => t
let {length : len} = 'get'; // len => 3

4、数值和布尔值的解构

  解构赋值的规则是,只要等号右边的值不是对象或数组,就将其转为对象。

5、函数参数的解构赋值

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

function add([x,y]){
    console.log(x +" "+ y);
}
add(); //报错, Cannot read property 'Symbol(Symbol.iterator)' of undefined
add([1]) // x => 1, y => undefined
add([1,2]); // x => 1, y => 2

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

function add({x = 0, y = 0} = {}){ // ={}是必须的,否则报错
    console.log(x +" "+ y);
}
add(); // x => 0, y => 0
add({}); // x => 0, y => 0
add({x: 3}); // x => 3, y => 0
add({x: 3, y: 4}); // x => 3, y => 4

注意 默认值应该赋给变量,而不是为函数的参数指定默认值。

function add({x,y} = {x : 0, y : 0}){
    console.log(x +" "+ y);
}
add(); // x => 0, y => 0
add({}); // x => undefined, y => undefined
add({x: 3}); // x => 3, y => undefined
add({x: 3, y: 4}); // x => 3, y => 4

6、圆括号问题

以下三种解构赋值不得使用圆括号:

  (1)变量声明语句,模式不能使用圆括号。

  (2)函数参数,函数参数也属于变量声明,因此不能带有圆括号。

  (3)赋值语句的模式部分不能使用圆括号。

// 全部报错
let [(a)] = [1]; // 第一种
function f([(z)]) { return z; } // 第二种
({ p: a }) = { p: 42 }; // 第三种

可以使用圆括号的情况只有一种:赋值语句的费模式部分可以使用圆括号:

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确

7、用途

  (1)交换变量的值。 [x, y] = [y, x]

  (2)从函数返回多个值。函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取这些值就非常方便。

  (3)函数参数定义,解构赋值可以方便地将一组参数与变量名对应起来。

  (4)提取JSON数据。

  (5)函数参数的默认值,可以避免在函数体内进行参数是否赋值的判断。

  (6)遍历Map解构。

for (let [key, value] of map) {
  console.log(key + " is " + value);
}

  (7)输入模块的指定方法。

const { SourceMapConsumer, SourceNode } = require("source-map");

阮一峰:ECMAScript 6入门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ES6解构赋值的好处有以下几点: 1. 简化代码:ES6解构赋值可以让我们更简洁地从数组或对象中提取值,并将其赋给变量。这样可以减少冗余的代码,使代码更加简洁易读。 2. 提高可读性:通过使用解构赋值,我们可以清晰地表达出我们想要提取的值的含义,使代码更易于理解和维护。 3. 方便的交换变量值:使用解构赋值可以方便地交换两个变量的值,而不需要使用额外的中间变量。 4. 快速提取对象属性:解构赋值可以快速提取对象中的属性,并将其赋给变量。这样可以方便地访问和操作对象的属性。 5. 函数参数的灵活应用:解构赋值可以用于函数参数中,可以方便地从传入的对象或数组中提取所需的值,使函数参数更加灵活。 6. 处理JSON数据:解构赋值可以方便地从JSON数据中提取所需的值,使得处理JSON数据更加方便快捷。 7. 支持默认值:解构赋值可以为变量设置默认值,当提取的值不存在时,可以使用默认值来代替,避免出现undefined的情况。 8. 多层嵌套解构:ES6解构赋值支持多层嵌套的解构,可以方便地从复杂的数据结构中提取所需的值。 9. 可以与扩展运算符结合使用解构赋值可以与扩展运算符(...)结合使用,可以方便地提取数组或对象中的部分值,并将其与其他值合并或进行其他操作。 总之,ES6解构赋值可以使我们的代码更加简洁、可读性更高,并且提供了更多的灵活性和便利性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值