解构赋值语法是一个Javascript
表达式,这使得可以将值从数组或属性从对象提取到不同的变量中,文中主要讲数组的解构赋值、对象的解构赋值、字符串的解构赋值、数值和布尔值的解构赋值以及函数参数的解构赋值
数组的解构赋值
基本用法
ES6以前我们如果要定义三个变量的话需要这样做:
code
var a = 1,
b = 2,
c = 3;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
使用解构赋值的话就好比“模式匹配”一般:
code
let [a, b, c] = [1, 2, 3];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
只要等号两边的模式一样,就可以成功解构赋值:
code
let [
[a, [b]], c
] = [
[1, [2]], 3
];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
如果两边的模式相同,但是右边少值的话就会解构不成功,导致左边的变量值为undefined
:
cdoe
let [
[a, [b]], c
] = [
[1, []], 3
];
console.log(a); // 1
console.log(b); // undefined
console.log(c); // 3
如果两边模式相同,但是左边少变量的话,依然可以将已有的变量赋值成功:
cdoe
let [
[a, [b]],
] = [
[1, [2]], 3
];
console.log(a); // 1
console.log(b); // 2
console.log(c); // ReferenceError: c is not defined
等号的右边如果不是可遍历的机构则会报错:
cdoe
let [a] = 1;
console.log(a); // TypeError: 1 is not iterable
let [a] = false;
console.log(a); // TypeError: false is not iterable
let [a] = NaN;
console.log(a); // TypeError: NaN is not iterable
let [a] = undefined;
console.log(a); // TypeError: undefined is not iterable
let [a] = null;
console.log(a); // TypeError: null is not iterable
let [a] = {};
console.log(a); // TypeError: {} is not iterable
指定默认值
在解构赋值中允许指定默认值。当一个位置没有值的时候,页就是当模式相同,但是右边没有值的时候可以指定默认值:
code
let [
[a, [b = 4]], c
] = [
[1, []], 3
];
console.log(a); // 1
console.log(b); // 4
console.log(c); // 3
注意:
ES6
内部使用严格相等运算符(===
)判断一个位置是否有值。所以只有当一个数组成员严格等于undefined
,默认值才会生效。
对象的解构赋值
变量的解构赋值和数组的解构赋值不太一样:
数组的解构赋值:元素是按次序排列的,变量的取值由变量所处的位置决定
对象的解构赋值:对象的属性没有次序,因此变量必须和属性同名才能取到 正确的值
*code
let { foo, bar } = { bar: '我是bar', foo: '我是foo' }
console.log(foo); // 我是foo
console.log(bar); // 我是bar
从代码中可以看出来对象解构赋值的时候是和顺序无关的,而属性名字就显得尤为重要。
变量名与属性名不一致时如何解构赋值
code
let { bar: foo } = { bar: '我是bar' }
console.log(foo); // 我是bar
console.log(bar); // ReferenceError: bar is not defined
以上代码的作用是把右边的bar
解构赋值给foo
,因为属性名不一样,所以需要用这种方式进行。
数组是特殊的对象
由于数组是特殊的对象,所以数组也支持对象属性的解构赋值:
code
let arr = [1, 2, 3];
let { 0: first, 1: second, 2: last } = arr;
console.log(first); // 1
console.log(second); // 2
console.log(last); // 3
字符串的解构赋值
字符串在进行解构赋值的时候其实是被转化成为了一个类数组的对象。
code
let [a, b, c, d, e, f] = 'string';
console.log(a); // s
console.log(b); // t
console.log(c); // r
console.log(d); // i
console.log(e); // n
console.log(f); // g
因为字符串具有length
这个属性,因此我们还可以对该属性进行解构赋值:
code
let { length: len } = 'string';
console.log(len); // 6
数值和布尔值的解构赋值
数值和布尔值也能进行解构赋值,此时他们都被转化为了对象。
code
let { toString: tos1 } = 456;
let { toString: tos2 } = false;
console.log(tos1 === Number.prototype.toString); // true
console.log(tos2 === Boolean.prototype.toString); // true
函数参数的解构赋值
函数的参数也可以进行解构赋值,这是一个解构赋值运用比较多的场景,其实就是对之前所讲的数组、对象、布尔值、数值解构赋值的一种实际使用:
code
function add([a, b]) {
return a + b;
}
console.log(add([2, 3])); // 5
这样做会让传参更加便捷,因为在传参的时候我们可以加入默认值,避免了a = ea || 0;
这种类似的语句出现。解构赋值还是很好用的,熟悉之后会让我们的js语句更加合理,更加易于维护。