参考阮一峰的ECMAScript 6 入门
变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值并对变量进行赋值,称为解构。
数组的解构赋值
// 完全解构
const [ , , [ , d, ]] = ['a','b',['c','d','e']];
const arr = ['a','b',['c','d','e']];
const [ , ,[ , ,e]] =arr;
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
const arr1 = [1,2];
const arr2 = ['a','b'];
const arr3 = [arr1,arr2];// [[1,2],['a','b']]
// 合并数组
const arr4 = [...arr1,...arr2];// [1,2,'a','b']
const arr5 = [1,2,3,4];
// 变量c = [3,4]
const [a,b,...c] = arr5;
默认值:
const arr6 = [1,null,undefined];
const [a1,b1=2,c1,d1='d'] = arr6;
用来接收多个函数返回值:
function getValue(id){
return [
true,
{
name: 'Dell',
gender: '男'
},
'返回成功'
]
}
const [status,data,msg] = getValue(111);
对象的解构赋值
1.对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
// foo="aaa" bar="bbb"
let {foo} = {bar: 'baz'};
// foo = undefined 解构失败
2.如果变量名与属性名不一致,必须写成这样:
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
// f='hello' l='world'
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。first是匹配的模式,f才是变量。真正被赋值的是变量f,而不是模式first。
3.稍微复杂的对象解构:
let person = {
id: 111,
msg: [{
name: 'Dell',
age: 21
},{
name: 'Kelly',
age: 22
},{
name: 'Kelly',
age: 23
}]
};
// 必须指定属性名msg(因为是提取数组中的某一个值) ,let不能重复声明变量,name:name1
let {id, msg:[msg1,{name},{name:name1}] } = person;
4.合并对象:
const obj1 = {
name: 'Dell',
age: 21
}
const person = {
gender: '男',
...obj1
}
5.对已经申明的变量进行对象的解构赋值:
// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
let x;
({x} = {x: 1});
6.默认值:默认值生效的条件是,对象的属性值严格等于undefined。null与undefined是不严格相等的。
var {x = 3} = {x: undefined};
// x=3
var {x = 3} = {x: null};
// x=null
- 对象结构赋值的主要用途
- 提取对象属性:
// 必须score:[score1](因为是提取数组中的某一个值) const {name,score:[score1],score} = { name: 'Dell', score: [80,85,90] } // name='Dell' score=80 score=[80,85,90]
- 使用对象传入乱序的函数参数:
function a({ url,data,type='css' }){ console.log(url); console.log(data); console.log(type); } a({ data: 1, url: '../css' }); // 输出: ../css 1 css
- 获取多个函数返回值:
function getValue(id){ return { status: true, data: { name: 'Dell', gender: '男' }, msg: '返回成功' } } const {status,data,msg} = getValue(111);
字符串的解构赋值
字符串也可以解构赋值,因为字符串被转换成了一个类似数组的对象。
const str = 'Hello';
const [a,b,c,...other] = str;
const [...str1] = str;
const str2 = str.split('');
const str3 = [...str];
// 结果都是一样 ["H", "e", "l", "l", "o"]
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
let {length : len} = 'hello';
// len=5
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true
数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
函数参数的解构赋值
函数的参数也可以使用解构赋值。
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。