解构赋值(Destructuring)
解构赋值(Destructuring)
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
数组的解构赋值
以前,为变量赋值,只能直接指定值。
let a = 1;
let b = 2;
let c = 3;
ES6 允许写成下面这样。
//等号左边是在数组中声明多个变量
//等号右边是一个数组
let [a, b, c] = [1, 2, 3];
console.log(a,b,c);//->1 2 3
上面的代码表示从,可以从数组中提取值,按照位置赋值给左侧的变量
默认值
解构赋值允许指定默认值。
//y在右侧数组中对应位置没有值,即undefined,会使用默认值
let [x,y=2]=[1] //x->1 y->2
//同上
let [x=1,y]=[,2] //x->1 y->2
//同上
let [x=1,y=2]=[] //x->1 y->2
注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined
,默认值才会生效。
let [x = 1] = [undefined];
x // 1let [x = 1] = [null];
x // null
默认值可以是一个表达式,只不过这个表达式是惰性的,使用到的时候才会执行求值。
function f(){ console.log("aaaaaa"); return 1; }
let [x=f()]=[];
//aaaaaa
//x->1
默认值可以引用解构赋值的其他变量,但该变量必须已经声明。
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
上面最后一个表达式之所以会报错,是因为x用y做默认值时,y还没有声明。
注意事项
- 如果解构不成功,那么变量的值将会是
undefined
let [foo] = [];
let [bar, foo] = [1];
以上两种情况foo
的值都是undefined
- 数组的解构可以用于嵌套赋值
let [x,[y,z],l]=[1,[2,3],4]
//x->1,y->2,z->3,l->4
- 解构存在不完全解构,即等号左边的模式,只匹配一部分等号右边的数组。这种情况下依然可以解构成功。
let [x, y] = [1, 2, 3];
x // 1
y // 2let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
以上两个例子都属于不完全解构,但是够可以成功。
- 如果等号右边的不是数组,严格的说不是可以遍历的结果,那么将会报错。
// 报错
let [foo] = 1; //VM415:1 Uncaught TypeError: 1 is not iterable
let [foo] = false; //VM415:1 Uncaught TypeError: false is not iterable
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
以上代码都会报错。
- 只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值
let [a,b,c]=new Set([1,2,3]);
//a->1,b->2,c->3
对象的解构赋值
解构赋值不仅可以用于数组,也可以用于对象。
//这里的变量名与对象的属性同名
let {foo,bar}={foo:"a",bar:"b"}
//foo->a bar->b
对象的解构与数组有一个重要的不同,数组中的元素是按照次序排列的,变量名的取值由他的位置决定;而对象没的属性没有次序,变量名必须与属性同名才能取到正确的值。即数组的结果是按照元素的次序给变量赋值,对象的解构是按照变量名和属性名匹配做赋值。
如果要赋值的变量名和对象属性名不一样,可以使用匹配模式:变量名称
写法。
//f、b为匹配模式,会去匹配同名的属性
//将匹配到的同名属性的值赋给foo、baz
let {f:foo,b:baz}={f:"a",b:"b"}
//foo->a bar->b
其实第一个示例代码的完整写法是这样的。
//这里的变量名与对象的属性同名
let {foo:foo,bar:bar}={foo:"a",bar:"b"}
//foo->a bar->b
默认值
对象的解构赋值也可以给默认值
let {foo='a',bar}={bar:'b'} //foo->a bar->b
let {foo='a',bar='b'}={} //foo->a bar->b
let {foo='a',bar=foo}={} //foo->a bar->a
var { message: msg = 'Something went wrong' } = {};
//msg->"Something went wrong"
使用默认值的条件是,对象属性值严格等于(===)undefined
let {foo='a'}={foo:undefined} //foo->a
let {foo='a'}={foo:null} //foo->null
注意事项
- 对象解构失败,默认值将会是
undefined
,这一点和数组解构赋值一致
let {foo,bar}={foo:"a"}
//foo->a bar->undefined
- 对象的解构也可以用于嵌套赋值,这一点和数组的解构嵌套赋值一致
let {foo,bar:{baz}}={foo:"a",bar:{baz:"b"}}
//foo->a,bar->b
下面是一个更为复杂的例子
const node = {loc: {start: {line: 1,column: 5}}
};let { loc, loc: { start }, loc: { start: { line }} } = node;
//loc->{start: {…}}
//start->{line: 1, column: 5}
//line->1
上面的代码进行了三个解构赋值,分别是loc、start和line。这里需要注意的是:loc解构赋值时,loc即时匹配模式又是变量;start解构赋值时,loc是匹配模式,start即使匹配模式又是变量;line解构赋值时,loc\start都是匹配模式,line即是匹配模式又是变量。
- 如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
// 报错
let {foo: {bar}} = {baz: 'baz'};
foo模式需要匹配一个对象,但是foo并没有匹配到一个对象,值将会是undefined
,undefined.bar
会报错。
几个用于巩固知识点的代码示例
- 解构一个对象,赋值给数组
function test(){let array=[];let obj={foo:'a',bar:'b'};({foo:array[0],bar:array[1]}=obj);console.log("array:",array);//["a", "b"]
}
test();
- 解构一个数组,赋值给对象
function test1(){var obj={foo:[],bar:[]};var array = [[1,2],['a','b']];([obj.foo,obj.bar]=array);console.log("obj:",obj);//{bar:["a", "b"],foo:[1, 2]}
}
test1()
- 对象和数组解构赋值嵌套使用
function test2(){var obj={userName:[{fistName:'Zhang'},{lastName:'Xueyuan'}]}var userNameObj={};var userNameAray=[];({userName:[{fistName:userNameObj.fistName},{lastName:userNameObj.lastName}]}=obj);({userName:[{fistName:userNameAray[0]},{lastName:userNameAray[1]}]}=obj);console.log("userNameObj:",userNameObj);//{fistName: "Zhang", lastName: "Xueyuan"}console.log("userNameAray:",userNameAray);//["Zhang", "Xueyuan"]
}
test2()
字符串的解构赋值
字符串也可以解构赋值,如果等号的右侧是字符串,那么该字符串会转换成数组对象(Array)
let [a,b]="ab"; //a->a b->b
//上面的代码相当于
let [a,b]=new Array('a','b');
字符串转换数组对象后,也可以使用对象的解构方式解构数组对象的属性
let {length:len}="ab"; //len->2
也就是说字符串的解构赋值,既可以使用对象的解构赋值,也可以使用数组的解构赋值。
数值和布尔值的解构赋值
数值和布尔值也可以解构赋值,如果等号的右侧是数值或布尔值,那么数值或布尔值将转换正对应的包装类,数值Number,布尔值Boolean。
let {valueOf:fun}=true;
let {valueOf:fun}=123;
//这里是把valueOf函数赋值给了变量,并不是将valueOf函数的执行结果赋值给fun
注意:数值和布尔值不能使用数组解构赋值,应该两者都不是可迭代(Iteration)的对象。
函数的参数解构赋值
解构赋值可以用于数组和对象,也可以用于函数的解构赋值。原理都是一样的,一个函数需要一个或多个顺序排列的形参,在调用是顺序传入实参,使用解构数组或对象的形式作为形参,调用的时候传入数组或对象作为实参。
//普通的写法
function add(x,y){return x+y;
}
add(1,2);//->3//使用数组解构赋值的形式给函数传递参数
function add([x,y]){return x+y;
}
add([1,2]);//->3//使用对象解构赋值的形式给函数传递参数
function add({x,y}){return x+y;
}
add({x:1,y:2});//->3
默认值
函数参数的解构赋值也可以使用默认值。
//函数参数数组解构赋值指定默认值
function add([x=0,y=0]=[]){return x+y;
}
console.log(add([1,2]));//->3 相当于[x=0,y=0]=[1,2]
console.log(add([1]));//->1 相当于[x=0,y=0]=[1]
console.log(add([]));//->0 相当于[x=0,y=0]=[]
console.log(add());//->0 //使用默认值[],相当于[x=0,y=0]=[]//函数参数对象解构赋值指定默认值
function add({x=0,y=0}={}){return x+y;
}
console.log(add({x:1,y:2}));//->3 相当于{x=0,y=0}={x:1,y:2}
console.log(add({x:1}));//->1 相当于{x=0,y=0}={x:1}
console.log(add({}));//->0 相当于{x=0,y=0}={}
console.log(add());//->0 //使用默认值{},相当于{x=0,y=0}={}
注意:[x=0,y=0]=[]
和{x=0,y=0}={}
等号左边是解构赋值的变量,右侧是调用函数不传入任何参数时使用的默认值,而不是指定x、y变量的默认值。add()
调用形式会使用默认值。
默认值非{}、[]的例子
function add([x=0,y=0]=[1,2]){return x+y;
}
console.log(add([1,2]));//->3
console.log(add([1]));//->1
console.log(add([]));//->0
console.log(add());//->3 //使用默认值{},相当于[x=0,y=0]=[1,2]
用途
- 交替变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取JSON
- 函数参数的默认值
- 便利Map接口
- 输入模块的指定方法
function forMap(){let map=new Map();map.set("name","zhangxy");map.set("age",30);for(let [key,value] of map){console.log(key,":",value);}
}
forMap();
//单独获取key
for(let [key] of map){console.log(key,":",value);
}//单独获取value
for(let [,value] of map){console.log(key,":",value);
}
总结起来解构赋值的语法让变量的赋值更简洁,用更少的代码就能从数组或对象中获取值赋给变量
学习资料:变量的解构赋值(https://es6.ruanyifeng.com/#docs/destructuring)
解构赋值(Destructuring)相关推荐
- ECMAScript 6的解构赋值 ( destructuring assignment)
var provinceValues=["010","020","028","0755","023" ...
- 【ES6】变量的解构赋值
[ES6]变量的解构赋值 一.什么叫解构赋值? 二.解构赋值有哪些分类?写法? 1)对数组的解构赋值 2)对对象的解构赋值 3)对字符串的解构赋值 4)对数值和布尔值的解构赋值 5)对函数参数的解构赋 ...
- ECMAScript6变量的解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring) ###数组的解构赋值 //ES5 //var a = 1; //var b = 2; //va ...
- es6学习 -- 解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定值. let a = 1; let b = 2; let c ...
- json解析 子类和父类同名属性如何赋值_想学变量的解构赋值?看完这一篇就够了...
序言 ES6允许按照一定模式从数组和对象中提取值,然后对变量进行复制,这被称为解构(Destructuring) 数组的解构赋值 基本用法 像上面的例子,可以从数组中提取值,按照对应位置对变量赋值,这 ...
- ES6的新特性(3)——变量的解构赋值
变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). let a = 1; let b = 2; le ...
- ECMAScript 6入门 - 变量的解构赋值
定义 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 解构赋值不仅适用于var命令,也适用于let和const命令. 解构赋值的规则是,只要 ...
- ES6之主要知识点(二) 变量的解构赋值。默认值
引自http://es6.ruanyifeng.com/#docs/destructuring 数组解构赋值 默认值 对象解构赋值 用途 1.数组的解构赋值 let [a, b, c] = [1, 2 ...
- es6分享——变量的解构赋值
变量的解构赋值:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前的写法: var a = 1; var b = 2; es6允许的写法 ...
最新文章
- 【数据结构】HashMap 面试题8问
- html5div上下滚动,html5 – 在另一个div上滚动div
- 编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]
- yii2-Ueditor百度编辑器
- jsp项目中连接数据库解决java.lang.ClassNotFoundException: com.mysql.jdbc.Driver的问题
- asyncio 并发测试
- 第16天学习Java的笔记(标准类,Scanner)
- caffe源码解析—image_data_layer层
- 牛客 - Strange Bulbs(bitset优化拓扑)
- 实践 HTML5 的 CSS3 Media Queries
- jQuery/javascript实现全选全不选
- CUDA精进之路(二):图像处理——形态学滤波(膨胀、腐蚀、开闭运算)
- 如何自定义设置Mac OS系统和windows系统键盘的方法
- 移动端开发框架mui介绍
- 论文的中期报告怎么写?
- C#-概念-类库:类库
- docker deamon源码学习
- c语言小球碰壁,小球碰壁效果
- FreeBSD+gnome3详细安装指南
- A Game of Thrones(97)
热门文章
- Rust语言——猜数游戏
- html5炉石传说3d相册,HTML5 可拖曳炉石传说3D卡片
- python直线水平_基于直线勘测水平图像矫正——python
- 哈佛大学心理学博士力荐
- php 中basename,php中的basename函数怎么用
- matlab 风电厂模板解释,基于MATLAB的风电场建模仿真研究牛步柯(原稿)
- logstash+elastic+kibana日志管理工具介绍及安装
- 原码,反码,补码,阶码,移码
- Python爬虫系列之爬取猫眼电影,没办法出门就补一下往期电影吧
- jQuery移除或禁用html元素点击事件常用方法