前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6中的解构赋值

ES6中的解构赋值

作者头像
刘亦枫
发布2020-03-19 17:34:23
8020
发布2020-03-19 17:34:23
举报

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

解构赋值是对赋值运算符的扩展。

他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

解构模型

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

1.解构的源,解构赋值表达式的右边部分。

2.解构的目标,解构赋值表达式的左边部分。

解构赋值

1.数组的解构赋值

代码语言:javascript
复制
var [a,b,c] = [1,2,3];
console.log(a);//1
console.log(b);//2
console.log(c);//3
//本质上这种写法属于‘模式匹配‘,只要等号两边的模式相同,左边的变量就会被赋予对应的值
let [foo,[bar]] = ["111",["abc"]];
console.log(bar); //abc

let [, ,third] = ["foo","bar","baz"];
console.log(third); //baz

let [x,y,z] = ['hah'];
console.log(y); //undefined
//如果解构不成功,变量的值就等于undefined

解构一般有三种情况,完全解构,不完全解构,解构不成功,在上述例子中存在完全解构和解构不成功的例子,下面来看一下不完全解构的例子

代码语言:javascript
复制
let [x,y] = [1,2,3];
console.log(x); //1
console.log(y); //2
let [a,[b],d] = [1,[2,3],4];
console.log(a); //1
console.log(b); //2
console.log(d); //4
//不完全解构:即等号左边的模式,只匹配一部分的等号右边的数组,这种情况下解构依然成功
代码语言:javascript
复制
//如果等号的右边不是数组,或者说不是可遍历的结构,那么将会报错
let [a] = 1;
let [b] = false;
let [c] = NaN;
let [d] = undefined;
let [e] = null;
let [f] = {};
//上面的语句都会报错:Uncaught TypeError: 1 is not iterable

2. 默认值

解构赋值允许指定默认值

代码语言:javascript
复制
let [x,y='b'] = ['a'];
console.log(y); //b

let [x,y = 'b'] = ['a',undefined];
console.log(y); //b ,数组成员为undefined时,默认值仍会生效(因为在ES6内部使用严格相等运算符‘===‘,判断一个位置是否有值,所以当一个数组成员严格等于undefined,默认值才会生效)

let [x,y = 'b'] = ['a',null];
console.log(y); //null,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined

3. 对象的解构赋值

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

代码语言:javascript
复制
 //1. 变量名与属性名一致的情况下
 let {foo,bar} = {foo : "aaa",bar : "bbb"}
 console.log(foo); //aaa
 console.log(bar); //bbb
 //变量名与属性名不一致的情况下,必须这样写
 let {a : name, b : age} = {a : 'zhangsan', b : 33};
 console.log(name); //zhangsan
 console.log(age);  //33

实际上 对象的解构赋值是以这样的形式简写的

代码语言:javascript
复制
 let {foo : foo ,bar : bar} = {foo : "aaa",bar : "bbb"}

也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者,第一个foo/bar 是匹配的模式,对应的foo/bar属性值才是变量,真正被赋值的是属性值(也就是第二个foo/bar), 如果不能理解再看下面这个例子

代码语言:javascript
复制
const node = {
    grand : {
        father : {
            line : 1,
            column : 5
        }
    }
 }

 let {grand,grand : { father},grand : {father : {column}}} = node;
 console.log(father); // {line : 1, column : 5}
 console.log(column); // 5
 // grand、fahter、column 分别对这三个属性解构赋值,grand、father是模式,只有column 是变量

4. 字符串的解构赋值

代码语言:javascript
复制
const [a,b,c,d,e] = 'hello';
console.log(a); //h
console.log(b); //e
console.log(c); //l
console.log(d); //l
console.log(e); //o

let { length : len} = 'yahooa';
console.log(len); //5,类似数组的对象都有一个length属性,还可以对这个属性解构赋值
  1. 数值和布尔值的解构赋值 解构赋值时,如果等号右边是数值和布尔值,则会先转为对象,但是等号右边为undefined 和 null时无法转为对象,所以对他们进行解构赋值时,都会报错
代码语言:javascript
复制
let {prop : x } = undefined;
console.log(x); //报错:Uncaught TypeError: Cannot destructure property `prop` of 'undefined' or 'null'

6.函数参数的解构赋值

函数的参数也可以使用解构参数

代码语言:javascript
复制
function move({x = 0,y = 0} = { }){
    return [x,y];
 }
console.log(move({x : 3,y : 4})); //[3,4]
console.log(move({x : 3})); //[3,0]
console.log(move({})); //[0,0]
console.log(move()); //[0,0]
//move()的参数是一个对象,通过对这个对象进行解构,得到变量x、y的值,如果解构失败,x和y 等于默认值
function move2({x,y} = {x : 1, y : 2 }){
    return [x,y];
}
console.log(move2({x : 6,y : 8})); //[6,8]
console.log(move2({})); //[undefined,undefined]
console.log(move2()); //[1,2]
//move2() 是为函数move的参数指定默认值,而不是为变量x和y指定默认值,所以与前一种写法的结果不太一样,undefined 就会触发函数的默认值

7.对象解构中的 Rest

代码语言:javascript
复制
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10 
b; // 20 
rest; // { c: 30, d: 40 }

8.解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)

代码语言:javascript
复制
// 声明对象 和 自身 self 属性
var obj = {self: '123'};
// 在原型链中定义一个属性 prot
obj.__proto__.prot = '456';
// test
const {self, prot} = obj;
// self "123"
// prot "456"(访问到了原型链)

解构用途

1.交换变量的值

代码语言:javascript
复制
let x = 1;
let y = 2;
[x,y] = [y,x];
console.log(x); //2
console.log(y); //1

2.从函数返回多个值 函数只能返回一个值,如果要返回多个值的话,只能将它们放在数组或者对象里返回

代码语言:javascript
复制
function example(){
   return {
       foo : 'a',
       bar : 'b'
   }
 }
 let {foo,bar} = example();
 console.log(foo); //a
 console.log(bar); //b

3. 函数参数的定义

代码语言:javascript
复制
//参数是一组有次序的值
function example([x,y,z]){
    return x + y + z;
}
example([1,2,3])
console.log(example([1,2,3])); //6
//参数是一组无次序的值
function f({x,y,z}){
    return x + y + z;
}
f({x : 'a', z : 'b', y : 'c' });

console.log(f({x : 'a', z : 'b', y : 'c' })); //acb
1

4.提取 JSON 数据

解构赋值对提取 JSON 对象中的数据,尤其有用。

代码语言:javascript
复制
let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
// 42, "OK", [867, 5309]

5.函数参数的默认值

代码语言:javascript
复制
jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
} = {}) {
  // ... do stuff
};

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || ‘default foo’;这样的语句。

6.遍历 Map 结构

任何部署了 Iterator 接口的对象,都可以用for…of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。

代码语言:javascript
复制
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
如果只想获取键名,或者只想获取键值,可以写成下面这样。

// 获取键名
for (let [key] of map) {
  // ...
}

// 获取键值
for (let [,value] of map) {
  // ...
}

7.输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。

代码语言:javascript
复制
const { SourceMapConsumer, SourceNode } = require("source-map");
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解构模型
  • 解构赋值
  • 解构用途
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档