乐趣区

ES6精解:变量的解构赋值

1. 数组的解构赋值
我们知道以前我们给一个变量赋值要这样如下:
let a = 1;
let b = 2;
let c = 3;
但是 ES6 出来之后,我们可以这样:
let [a, b, c] = [1, 2, 3]
以上就是从数组中提起值,一一对应赋值,a、b、c 分别为 1、2、3
let [aa, [[bb], cc]] = [1, [[2], 3]]
aa,bb,cc 分别对应 1,2,3
let [,,d] = [10, 20, 30];
console.log(d);
d 的值为 30
let [e, …f] = [1, 2, 3, 4, 5];
e 为 1, f 为 [2,3,4,5]
let [x, y, …z] = [1];
x 为 1,y 为 undefined,z 为 [],如果没有对应值会等于 undefined
解构赋值也允许默认值,如下:
let [x = ‘ 默认值 ’] = [];
x 的值为默认值
let [a = 123] = [undefined];
let [b = 321] = [null];
a 的值为 123,b 的值为 321,因为 ES6 中是严格遵循(===),所以只有当数组对应的值为 undefined 的时候,才能等于默认值
默认值可以引用解构赋值的其他变量,但是这个变量必须得声明过的,如下:
let [a = 0, b = a] = [];
这里 a、b 分别为 0,0
但是如果这个变量没有声明,就会报错,如下:
let [a = b, b = 1] = [];
这里就会报错:Uncaught ReferenceError: b is not defined
2. 对象的解构赋值
let {a, b} = {a: 1, b: 2};
a,b 的值为 1,2
对象解构赋值可以无需按照顺序一一对应,但是括号两边的变量名称和属性名称要相同,才能取到正确值
let {a, b} = {a: 1, c : 2};
a 为 1,b 为 undefined,这里 b 在右边括号中没有对应的属性值与其对应,所以此时 b 为 undefined
如果变量名和属性名不一样,则要按照如下写:
let {aa: fa, bb: fb} = {aa: 1, bb: 2};
fa 为 1,fb 为 2
这里可以说明,对象解构赋值实际上是如下的简写:
let {aa: aa, bb: bb} = {aa: 1, bb: 2}
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
let {aa: fa} = {aa: 1}

//fa 为 1
//aa 为 Uncaught ReferenceError: aa is not defined
这里就说明了,fa 是真正被赋值的, 此时的 aa 是模式而不是变量,如果你要让 aa 为变量,则如下:
{
let {aa: fa, aa} = {aa: 1};
// aa 为 1
// fa 为 1
}
此时 aa 为 1,bb 为 1, 此时 aa 就是变量了
当然对象也可以多层嵌套如下:
{
let obj = {
p: [1, { y: 2}]
}

let {p: [x, { y}]} = obj;
console.log(x); // 1
console.log(y); // 2
}

{
let obj = {};
let arr = [];
({a: obj.name, b: arr[0] } = {a: 321, b: 123});

console.log(obj); // {name: 321}
console.log(arr); // [123]
}
对象解构默认值:
{
let {x = 1} = {};
console.log(x); //1
}

{
let {x : y = 4} = {};
console.log(y); //4
}

{
let {x : y = 4} = {x: 5};
console.log(y); //5
}

默认属性生效条件必须是对象的属性严格等于 undefined,如果是 null 就不会生效,如下:
{
let {x = 1} = {x : null};
console.log(x); //null
}
已声明的变量解构赋值:
{
let x;
({x} = {x : 1});
console.log(1); // 1
}
得要加个小括号才可以,否则会报错;
数组对应对象属性的解构:
{
let arr = [1, 2, 3];
let {0 : one, [arr.length-1] : three } = arr;
console.log(one); // 1
console.log(three); // 3
}
3. 字符串的解构赋值
字符串也可以解构赋值,因为字符串可以转换成一个类似数组的对象
{
let [a, b, c, d] = ‘hero’;

console.log(a); //h
console.log(b); //e
console.log(c); //r
console.log(d); //o
}
类似数组的对象都有一个 length 属性,可以对这个属性解构赋值
{
let {length: len} = ‘hero’;
console.log(len); // 4
}
4. 数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值或者布尔值时,则会先转换成对象
{
let {toString: s} = 123;
console.log(s === Number.prototype.toString); //true
}

{
let {toString: s} = true;
console.log(s === Boolean.prototype.toString); //true
}
解构赋值的规则:如果等号右边的值不是对象或者数组则会先转为对象,由于 undefined 和 null 无法转为对象,所以无法对它们进行解构赋值,会报错,如下:
{
let {props: x} = undefined; // 报错
let {props: y} = null; // 报错
}
5. 函数参数的解构赋值
{
const arr = [[1,2],[3,4]].map(([a, b])=> a+b);
console.log(arr); //[3,7]
}
函数参数默认值:
function func({x = 0, y = 0} = {}) {
return [x, y];
}

console.log(func({x:5,y:6})); //[5,6]
console.log(func({x:5})); //[5,0]
console.log(func({})); //[0, 0]
console.log(func()); //[0, 0]
如果按照以下定义就不同了,如下:
function fn({x, y} = {x: 1, y: 2}) {
return [x, y];
}
console.log(fn({ x: 11, y: 22})); // [11, 22]
console.log(fn({ x: 11})); // [11, undefined]
console.log(fn({})); // [undefined, undefined]
console.log(fn()); // [1, 2]
undefined 会触发函数参数的默认值,如下:
{
const a = [1, undefined, 3].map((x = ‘noundefine’) => x);
console.log(a); //[1, “noundefine”, 3]
}
6. 圆括号问题
圆括号只能一种情况才能使用:赋值语句的非模式部分,可以使用圆括号
[(b)] = [3]; // 正确
({p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
上面三行语句都可以正确执行,因为首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是 p,而不是 d;第三行语句与第一行语句的性质一致。
本文参考链接:http://es6.ruanyifeng.com/#do… 主要是看了阮一峰老师的文章,自己整理了一下,供后期自己看笔记用的

退出移动版