ES2015中允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,被称为”解构(Destructering)“。

以前,为变量赋值,只能指定值。

     /**
* 以前,为变量赋值,只能直接指定值
* **/
let a = 1;//第一种:变量赋值
let b = 2;
let c = 3;
/**
* 现在ES2015允许这样:数组和对象
* **/
let [a,b,c] = [1,2,3];//第二种:数组的解构赋值
let {a,b,c} = {
a:1,
b:2,
c:3
};//第三种:json对象解构赋值

本质上,后两种通过解构赋值的写法属于”模式匹配“,只要判定了等号两边的模式相同(解构),左边的变量就会被赋予对应的值即赋值。

数组的解构赋值

上面例子第二种就是数组解构赋值,这是刚好完全解构的情况,还有两种不完全解构的情况:

   /**
* 不完全解构的情况
*/
{
let [a,b,c] = [1,2];//c的值:undefined
console.log(a,b,c);//1 2 undefined
} {
let [a,b] = [1,2,3];//右侧多了一个3
console.log(a,b);//1,2
} {
let [,,c] = [1,2,3];//c 3
console.log(c);//
}
/**
* 由此例子可以看到当左侧的c没有解构成功时(即右侧的数据结构没有与之对应的部分),那么这个变量的值为undefined
* 那么这个变量的值为undefined,我们知道某个值为undefined的时候存在两种情况:
* 一种是生命了没有赋值
* 另一种是显示赋值为undefined
* **/
 {
const [d] = [];
console.log(d);//undefined
//没有解构成功的变量会被显式赋值为undefined
}

当数组内部有嵌套时,解构依然能正常进行:

 {//可以嵌套
let [a,[b,c],d] = [1,[2,3],4];
console.log(a,b,c,d);
}

除此之外还允许为解析解构设定默认值,即变量在解构后没有被赋到值(严格来说,应该被赋值为undefined)的情况下允许赋予变量某个默认值:

        let [foo = true] = [];
console.log(foo);//true let [x,y="bbb"] = ["a"];
console.log(x,y);//a bbb let [x,y= "b"] = ["a",undefined];
console.log(x,y);//a b let [x = 4] = [undefined];//在变量有默认值的时候,只有当解构之后赋的值为undefined时,默认值才会生效,否则默认值会被解构之后的值覆盖。
console.log(x);//4 let [x = {a:12}] = [null];//null是对象,不为空。
console.log(x);//null

当默认值为表达式时,表达式的求值是惰性的。

 function f(){
console.log("aaa");
}
//let [x] = [1];
//let [y] = [];
let [z = f()] = [];
let [z1 = f()] = [undefined]; let [a = f()] = [1]; //console.log(x);//1
//console.log(y);//undefined
console.log(z,z1);//aaa aaa undefined undefined 当然如果右侧换成[][undefined]的话,f()执行。
console.log(a);//1 因为被解构的值是1,所以默认值不会生效,于是f()也就没有必要执行,它也确实没有执行,因为如果执行的话,会打印aaa。
//当默认值为表达式时,表达式的求值时惰性的。

默认值还可以引用解构赋值的其他变量,但前提是该变量必须已经声明,即被引用变量必须排在引用变量的前面。

         //let [x = 1, y = x] = [];//1 1
//let [x = 1, y = x] = [2];//2 2 先确定x的值是2
//let [x = 1, y = x] = [1,2]; //1 2
let [x = y,y = 1] = [];//ReferenceError引用错误 原因:x用到默认值y的时候,y还没有被声明。 console.log(x,y);

对象的解析赋值

赋值规则与数组的解构赋值本质上是一样的,都是解析等号两边的模式,然后将对应位置上的数据关联起来。但与数组不同的是,对象是通过键来区分内部成员的,而非数组里面的位置,所以对象的解构与变量的位置无关。

         // let {a,b} = {
// b: 2,
// a: 23
// };
// console.log(a,b);//23 2 // let {a, b} = {a:23,b:2};//简写
// let {a:a, b:b} = {a:23,b:2};//全写
// console.log(a,b); let {a:c, b:d} = {a:23,b:2};
console.log(c,d);         console.log(c,d);//undefined 这里的a,b并非变量,是用来匹配的模式,所以没有定义。 // let a = 1;
// let obj = {a};
// console.log(obj);//{a:1} // let a = 1;
// let obj = {a: a};
// console.log(obj);//{a:1}

与数组一样,解构也可以用于嵌套解构的对象:

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

字符串的解析赋值

字符串也可以解构赋值,这是因为此时,字符串被转换成了一个类似数组的对象。

         const [a,b,c,d] = "meng";
console.log(a,b,c,d);//m e n g const {length} = "meng";
console.log(length);//

同时,作为三个基本包装类型之一,字符串还可以调用String对象的一些方法:

let {indexOf} = "meng";
console.log(indexOf === String.prototype.indexOf);//true

可以知道,解构赋值时,如果等号右面时数值、字符串和布尔值三种基本包装类型,则会优先转化为对象。

参数的解析赋值

参数的解构赋值本质数组的解构赋值或者对象的解构赋值。

      //函数传参解构:讲一个数组或者对象作为参数传进一个函数,真正能被函数感知的是参数解构之后被赋值的变量。
function show({a,b}){
console.log(a,b);
}
show({
a:1,b:2
}); //函数传参解构2默认值
function show2({a,b="默认"}){
console.log(a,b);
}
show2({
a:1
}); //函数传参解构全部默认
function show3({a="hhdhd",b="默认"}){
console.log(a,b);
}
show3({}); //函数特性
function show4({a="hhdhd",b="默认"}={}){
console.log(a,b);
}
show4();

在React无状态组件时:

    ComponentA = (props) => {
return (
<div>props.name + props.age</div>
);
} //改进
这里props是组件实例化时传入一个包含所有prop的对象,可以解构成:
ComponentA = ({name,age}) => {
return (
<div>name + age</div>
);
}

默认值情况:

         //{x = 0,y = 0} = {}
//参数X和Y在解构时的默认值是0,同时设置函数move的的默认参数是{},
//当什么都没有传给函数move的时候,就等于把{}传给move,
//此时,x和y有一个默认的解构时候0。当传入函数的值,解构后可以对x和y赋值时,则为x,y为新赋的值。
function move({x = 0,y = 0} = {}){
return [x,y];
} let aaa = move({x:3,y:8});//[3,8]
aaa = move();//[0,0]
aaa = move({x:3});//[3,0]
aaa = move({});//[0,0]
console.log(aaa);

另一个demo:

         //function move({x:0,y:0}) {x,y}= {x:0,y:0}的意思不是单独为x和y赋默认值只能函数的参数赋默认为{x:0,y:0},意即当什么都没有传入的时候,等于将{x:0,y:0}传给函数
       //所以当将{}作为参数传入的时候,{x,y}={}解析之后[undefined,undefined]
function move({x,y} = {x:0,y:0}){
return [x,y];
} let aaa = move({x:3,y:8});//[3,8]
aaa = move();//[0,0]
//aaa = move({x:3});//[3,undefined]
//aaa = move({});//[undefined,undefined]
console.log(aaa);

总之,第一个例子是:对象解构赋值的默认值+函数参数的默认值;

第二个例子,函数参数默认值。

ES2015中的解构赋值的更多相关文章

  1. ES6中的解构赋值

    在解释什么是解构赋值前,我们先来看一下, ES5 中对变量的声明和赋值. var str = 'hello word'; 左边一个变量名,右边可以是字符串,数组或对象. ES6 中增加了一种更为便捷的 ...

  2. 【JS】325- 深度理解ES6中的解构赋值

    点击上方"前端自习课"关注,学习起来~ 对象和数组时 Javascript 中最常用的两种数据结构,由于 JSON 数据格式的普及,二者已经成为 Javascript 语言中特别重 ...

  3. 变量的解构赋值////////////z

    变量的解构赋值 数组的解构赋值 对象的解构赋值 字符串的解构赋值 数值和布尔值的解构赋值 函数参数的解构赋值 圆括号问题 用途 数组的解构赋值 基本用法 ES6允许按照一定模式,从数组和对象中提取值, ...

  4. ES6 变量的解构赋值

    数组的解构赋值     var [a,b,c] = [1,2,3];    左边是变量,右边是值,根据数据结构一一对应 只要等号两边的模式相同,左边的变量就会被赋予右边对应的值,必须模式相同 如果等号 ...

  5. Es6 新增解构赋值

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

  6. ES6解构赋值

    前面的话 我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段.在ES6中添加了可以简化这种任务的新特性:解构.解构是一种打破数据结构,将其拆分为更小部分的过程.本文将详细介绍ES6解构赋值 ...

  7. ECMAScript 6之变量的解构赋值

    1,数组的解构赋值 基本用法 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定值. var a = 1; va ...

  8. ES6里的解构赋值

    我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段.在ES6中添加了可以简化这种任务的新特性:解构.解构是一种打破数据结构,将其拆分为更小部分的过程. 一.引入背景 在ES5中,开发者们为 ...

  9. 03 | 变量的解构赋值 | es6

    变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定值. let a ...

随机推荐

  1. js获取上月的最后一天

    一.问题: 在最近的开发中遇到一个需求,需要初始化默认时间为上月的最后一天 而在日历中这个值在每个月都不是固定的 二.分析: 问题可以转化为,获取指定月份时间的月末最后一天,下边是代码,供大家参考 f ...

  2. weka使用笔记3---classfily API调用

    分类器在数据挖掘中的作用不言而喻,weka中的分类器有很多种类型,但是weka在输出结果中,只输出了一个分类的预测的类型,没有输出分类的得分,有一些不给力.如果想知道得分和其预测的类的话,就得调用we ...

  3. bzoj1854 [Scoi2010]游戏 ([SCOI2010]连续攻击游戏)

    bzoj1854 [Scoi2010]游戏 ([SCOI2010]连续攻击游戏) 据说正解是并查集???我不会 这不是一道匈♂牙利好题吗??? 一个装备的两个属性都向它连边,然后跑一遍匈♂牙利 注意: ...

  4. dp合集 广场铺砖问题&&硬木地板

    dp合集 广场铺砖问题&&硬木地板 很经典了吧... 前排:思想来自yali朱全民dalao的ppt百度文库免费下载 后排:STO朱全民OTZ 广场铺砖问题 有一个 W 行 H 列的广 ...

  5. Hibernate各种主键生成策略与配置详解(转)

    原文链接:http://www.cnblogs.com/hoobey/p/5508992.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate ...

  6. iOS 上架的坑

    有3D-touch机型的坑 昨天在上线的时候遇到了一个坑,最后导致的结果是找了好几个小时,直接到半夜才能上线. 入正题: 坑是:项目运行在456上没什么问题,但是在6S以上的机型就有点击事件不响应的情 ...

  7. Spring学习(四)-----Spring Bean引用同xml和不同xml bean的例子

    在Spring,bean可以“访问”对方通过bean配置文件指定相同或不同的引用. 1. Bean在不同的XML文件 如果是在不同XML文件中的bean,可以用一个“ref”标签,“bean”属性引用 ...

  8. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)

    在飞机大战游戏开发中遇到的问题和解决方法: 1.在添加菜单时,我要添加一个有背景的菜单,需要在菜单pMenu中添加一个图片精灵,结果编译过了但是运行出错,如下图: 查了很多资料,调试了很长时间,整个人 ...

  9. pytest使用笔记(一)

    使用环境及预置条件:pycharm+win10+python3.6+pytest 1,创建示范的测试功能脚本,另存为test_sample.py,代码如下: # test_sample.py def ...

  10. Jmeter资源监控工具ServerAgent运行原理的一些研究

    用过Jmeter的应该都了解,有个ServerAgent工具,放在linux或者windows服务器上开启服务后,在Jmeter中配置下监视器,就可以抓取到服务器的一些资源信息,抓取的主要是cpu.内 ...