话说,解构无处不在啊,鄙人自从用了vue写项目以来,总是遇到各路大神莫名其妙的写法,然并未出任何错,查之,然解构也,呜呼哀哉,进而习之。

解构(Destructuring):是将一个数据结构分解为更小的部分的过程。ES6中,从数组和对象中提取值,对变量进行赋值。

解构有什么用处呢?可以大大的简化数组或者对象里面的元素的赋值语句。

数组解构,数组本身并没有发生任何的改变,解构是对新的变量(可能是对象同名属性)赋值。

//变量的声明
let [a,b,c] = [1,2,3];
//嵌套解构
let [foo,[bar],baz] = [1,[2],3];
//类似函数的剩余参数,数组解构有个类似的,剩余项的概念。 ...tail,里面的tail就是剩余项,也是个数组
let [head,...tail] = [1,2,3,4]; //head:1,tail:[2,3,4]
let [x,y,z] = new Set(['a','b','c']);
//解构允许指定默认值
let [foo = true] = []; //foo:true
let [x,y='b'] = ['a']; //x = 'a',y = 'b'

如果你只想获取数组中的第三个元素,则不必给前两项提供变量名。栗子如下:

let colors = ["red","green","blue"];
let [,,thirdColor] = colors;
console.log(thirdColor) //blue

JS中有个被遗漏的功能:克隆数组,ES5中用concat,用来合并数组,如果不传递任何参数,就是原数组的克隆品。ES6中可以使用剩余项达到同样的效果:

let colors = ["red","green","blue"];
let [...cloneColors] = colors;
console.log(cloneColors) //["red", "green", "blue"]

本例中剩余项将colors数组的值复制到cloneColors数组中,这个技巧值的关注。。。剩余项是数组解构模式中最后一项,后面不能有逗号。。。

对象的解构:

let {foo,bar} = {foo:"aaa",bar:"bbb"};
//实例举例,下面的变量x就是1,y是2,c为定义是is no defined
var obj = {x:1,y:2,c:1};
let {x,y} = obj; let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
//如果对象的属性已被变量赋值,再次赋值时候需要用圆括号括起来,因为花括号里面并不是块语句,而是解构赋值表达式。
let node = {
   type:'Identifier',
     name:'foo'
  },type = "Literal",name = 5;
  ({type,name} = node);
  console.log(type,name); //Identifier foo

对象的解构变量必须与属性同名,才能取到争取的值。而且对象的属性是没有次序的,而数组的元素是按次序排列的。如果想要变量名和属性名不一致,那么必须这样写:

let {foo:baz,hand:lochand = 'eart'} = { foo: "aaa", bar: "bbb" };
baz //'aaa',此时的foo就是未定被定义的,定义的变量只有baz
lochand //'eart' 此时的hand虽然undefined,但是lochand有被初始化
let {foo:foo,bar:bar} = {foo:"aaa",bar:"bbb"}

实际上也说明,对象的解构赋值是内部机制,先找回同名属性,再赋值给对应的变量,真正被赋值的是后者。现在已经掌握了如何对属性值为基本类型值的对象进行解构,而对象解构也可被用于从嵌套的对象结构中提取属性值。(嵌套对象表示:对象的属性可能还是一个对象)举个例子:

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, column: 1}、
let {loc:{start:localStart}} = node;
console.log(localStart) //{line: 1, column: 1}

嵌套对象的模式,里面使用了{},表示在node对象的loc属性内部寻找start属性。每当有个冒号在结构模式中出现,冒号之前的标识符代表需要检查的位置,冒号右侧则是赋值的目标;当冒号右侧存在花括号时,表示目标被嵌套在对象的更深层次中。

在对象的嵌套解构中也是可以给本地变量使用不同的名称,看上面的栗子(node.loc.start的值被存储在一个新的本地变量localStart上):

混合解构:

对象和数组解构能被组合使用,以创建更复杂的解构表达式。栗子如下:

let node = {
type:'Identifier',
name:'foo',
loc:{
start:{
line:1,
column:1
},
end:{
line:1,
column:4
}
},
range:[0,3]
};
let {
loc:{start},
range:[startIndex]
} = node;
console.log(start,startIndex); //{line: 1, column: 1} 0

上面的代码提取出node.loc.start和node.range[0],并将它们的值分别存储在start和startIndex上。

参数解构:

解构还有一个很有用的场景,在传递函数参数时,当JS函数接收大量可选参数时,一种常用模式是创建一个包含附加参数的options对象:

function setCookie(name,value,options){
options = options || {};
let secure = options.secure,
path = options.path,
domain = options.domain;
}
setCookie("type","js",{
secure:true,
path:'http://baidu.com'
})
function setCookie(name,value,{secure,path,domain}){
     //设置cookie的代码
setCookie("type","js",{
   secure:true,
   path:'http://baidu.com'
})

name和value参数是必需的,而options中的secure,path等是可选的。参数解构提供了更清楚标明函数期望输入的替代方案。用对象或数组解构的模式替代了具名参数。看上面的栗子,解构参数在未传递值的情况下会被设定为undefined,类似于常规参数。

圆括号和解构赋值的关系:

只要有可能导致解构歧义,就不得不使用圆括号。

let x = 2;
({x} = {x:1});
console.log(x) //1
//对象的解构赋值可很方便的将现有对象的方法,赋值到某个变量
let {log,sin,cos} = Math;
//由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构
let arr = [1,2,3];
let {0:first,[arr.length-1]:last} = arr;
first //
last //

对于字符串,数字,布尔值的解构赋值规则:只要等号右边的值不是对象或者数组,就先将其转化为对象,undefined和null是无法转化为对象,所以对它们进行解构赋值会报错。

[[1,2],[3,4]].map(([a,b]) => a+b)  //[3, 7]

对于函数的解构赋值,可以将形参以数组的形式传入,如上,数组参数被解构成变量a和b,对于函数内部就只是参数a,b。

用途:

1,变量交换:看起来如同镜像。赋值语句的左侧的解构模式,右侧是临时创建的数组字面量。x被赋值为数组中的y,y被赋值为数组中的x。

let x = 1;
let y = 2;
[x,y] = [y,x]

2,函数返回多个值

function example(){return [1,2,3]}
let [a,b,c] = example();
function example(){return {foo:1,bar:2}}
let {foo,bar} = example();

3,函数参数的定义

解构赋值可以方便的将参数和变量名对应起来,可以无次序

function f({x,y,z}){...}
f({z:2,y:8:x:9})

4,提取JSON数据,有关json的提取就是对象的解构赋值而已。

5,函数参数的默认值

指定参数的默认值,就避免了在函数体内再写 || 语句。

jQuery.ajax  = function(url,{
async = true,
beforeSend = function(){},
cache = true,
complete = function(){},
crossDomain = false,
global = true,
} = {}){ }
//这种写法有个缺点,当传入参数值为null时会引发程序异常。因为null和undefined是无法被解构的。

6,输入模块的指定方法

import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

关键字:【对象】【数组】【参数解构】

古今之成大事业,大学问者,必经过三种之境界:“昨夜西风凋碧树。独上高楼,望尽天涯路。”此第一境也。“衣带渐宽终不悔,为伊消得人憔悴。”此第二境也。“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”此第三境也。   ——王国维《人间词话》

es6的解构函数的更多相关文章

  1. ES6 的解构赋值前每次都创建一个对象吗?会加重 GC 的负担吗?

    本文来源于知乎上的一个提问. 为了程序的易读性,我们会使用 ES6 的解构赋值: function f({a,b}){} f({a:1,b:2}); 这个例子的函数调用中,会真的产生一个对象吗?如果会 ...

  2. 深入理解ES6之解构

    变量赋值的痛 对象 let o = {a:23,b:34}; let a = o.a; let b = o.b; 如上文代码,我们经常会遇到在各种场合需要获取对象中的值的场景,舒服一点的是获取单个属性 ...

  3. ES6 对象解构

    ES6 对象解构 第一眼看到,什么鬼? const { body } = document `` 其实等于: const body = document.body ``` http://es6.rua ...

  4. ES6语法~解构赋值、箭头函数、class类继承及属性方法、map、set、symbol、rest、new.target、 Object.entries...

    2015年6月17日 ECMAScript 6发布正式版本 前面介绍基本语法,  后面为class用法及属性方法.set.symbol.rest等语法. 一.基本语法:  1.         定义变 ...

  5. 进军es6(2)---解构赋值

    本该两周之前就该总结的,但最近一直在忙校招实习的事,耽误了很久.目前依然在等待阿里HR面后的结果中...但愿好事多磨!在阿里的某轮面试中面试官问到了es6的掌握情况,说明es6真的是大势所趋,我们更需 ...

  6. Es6 新增解构赋值

    1.数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 要想实现解构,就必须是容器,或者具有可遍历的接口. 以前,为 ...

  7. ES6 之 解构赋值

    本博文配合 阮一峰 <ES6 标准入门(第3版)>一书进行简要概述 ES6 中变量的解构赋值. 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这 ...

  8. ES6变量解构赋值

    ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构ES6之前我们申明多个变量需要按照下面的方法: let l a=1; let b=2; let c=3; let d=4; ...

  9. es6变量解构赋值的用途

    这里是我觉得es6解构赋值,在平时我们写js的时候非常有用,而且经常用到的地方,能简化我们的代码,让写代码简介优雅易读; 用途 1.交换变量的值,太方便了这逼,写法不仅简介而且一看就明白 let [x ...

随机推荐

  1. EXAM-2018-8-9

    EXAM-2018-8-9 B 水题 注意理解题意 有坑 G 博弈 观察发现 总是会进行到最后两个,或者先手取完全部,再特判一下只有一张牌的情况 H 九连环 通过找规律 我们可以得出递推式: F[n] ...

  2. Oracle-PL/SQL语句

    1.PL/SQL 2.存储过程,函数 3.java中调用存储过程和函数 4.触发器 1 PL/SQL 1.1什么是PL/SQL? n  PL:Process Language n  PL/SQL是or ...

  3. js手机浏览器video标签会一直置顶,遮盖住弹出层问题

    <video x5-playsinline="" playsinline="" webkit-playsinline="">&l ...

  4. 接口测试时返回的响应报json错误

    问题: 测试接口时,传入错误数据,最开始对于错误数据也返回了json数据的响应:后来传入错误数据,接口突然就没有返回json数据,通过在出错的代码之前进行打印,发现接口报500了 检查错误的方法1:在 ...

  5. 自定义servlet重写doGet或doPost方法是如何实现多态的

    我们知道,如果我们自定义一个servlet继承HttpServlet,并且重写HttpServlet中的doGet或doPost方法,那么从浏览器发送过来的request请求将调用HttpServle ...

  6. python中coding:utf-8的作用

    或者

  7. axios 传对象(JavaBean)到后台

    //user对象 let user = JSON.stringify({ userAccountNumber: own.userName, userPassword: own.userPassword ...

  8. JDBC连接到数据库查询打印数据

    通过一天的视频学习,认识了jdbc的连接原理前来小结: 游标读取数据库表的行一次读取一个,getXxx()方法读取表的列一个数据 next()方法可以让游标下移 可以把数据库的表看做是一个类,每条记录 ...

  9. spring基于@Value绑定属Bean性失

    用spring注解@Value绑定属性失败 环境: eclipse Version: Luna Release (4.4.0) spring 4.0 Junit4 其他依赖包 描述: JsrDAO类, ...

  10. Docker Linux下安装

    下载脚本并运行安装: sudo wget -qO- https://get.docker.com/ | sh wget:下载文件工具, -q:不显示指令执行过程, -O-:-O-以'-'作为file参 ...