ECMAScript 6(3)变量的解构赋值
目录
变量的解构赋值
数组的解构赋值
常规赋值
嵌套数组
右边不是数组 (报错)
set 解构
- 具有 Iterator 接口
带默认值的数组解构赋值
常规情况
哪种情况下默认值生效
对象的解构赋值
常规情况
变量名就是key
- 解构失败
解构赋值时,赋值形式并非深度复制
对已有变量进行解构赋值
- 用解构赋值可以方便的取出其他对象中的某个方法或属性
左边数组右边只能是数组;左边对象,右边可以是数组,或对象
- 默认值
字符串的解构赋值
数值和布尔值的解构赋值
函数参数的解构赋值
常规情况
默认值
解构赋值的用途
交换变量的值
从函数返回多个值
函数参数的定义
提取 JSON 数据
函数参数的默认值
遍历 Map 结构
输入模块的指定方法
变量的解构赋值
- 简单的来说,就是等号左右两边的数组/结构类似时,将右边的值直接赋给左边对应位置的变量;
- 主要面对的是数组和对象;
数组的解构赋值
1. 常规赋值
let [a, b, c] = [1, 2, 3];
a; //1
b; //2
c; //3
2. 嵌套数组
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined 如果解构不成功,变量的值就等于undefined。
z // []
3. 右边不是数组 (报错)
// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
4. set 解构
let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"
5. 具有 Iterator 接口
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
带默认值的数组解构赋值
1. 常规情况
var [a, b = 2, c, d = 10]=[1, , 3, 4];
a; //1
b; //2
c; //3
d; //4
2. 哪种情况下默认值生效
ES6 内部使用严格相等运算符(
===
),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined
,默认值才会生效
var [a = 1] = [undefined]; //1
var [a = 1] = [null]; //null
var [a = 1] = [3]; //3
var [a = 1] = ["abc"]; //"abc"
var [a = 1] = [{m: 1}]; //{m:1}
var [a = 1] = [true]; //true
var [a = 1] = [NaN]; //NaN
对象的解构赋值
- 简单来说,对象解构是根据key给变量赋值该key的value,数组解构是根据顺序给对应位置的变量赋值;
注意 : 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
1. 常规情况
var {'abc': a} = {'abc': 1};
a; //1
2. 变量名就是key
var {abc} = {'abc': 1};
abc; //1
ps : 对象中key 和value相同可以简写成 ,上面的代码实质就是
var {abc: abc} = {'abc': 1};
3. 解构失败
如果解构失败,变量的值等于undefined
。
简单来说就是, 左边的变量 在右边没有对应的key
let {foo} = {bar: 'baz'};
foo // undefined
4. 解构赋值时,赋值形式并非深度复制
var a = {
b: {c: 1}
};
a.b.c; //1
var {b} = a;
b.c; //1
b.c = 2;
b.c; //2
a.b.c; //2
5. 对已有变量进行解构赋值
// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
上面代码的写法会报错,因为 JavaScript 引擎会将{x}
理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
// 正确的写法
let x;
({x} = {x: 1});
6. 用解构赋值可以方便的取出其他对象中的某个方法或属性
var computed = {
add: function (a, b) {
return a + b;
},
minus: function (a, b) {
return a - b;
}
};
var {add, minus} = computed;
add(2, 3);
minus(2, 3);
7. 左边数组右边只能是数组;左边对象,右边可以是数组,或对象
假如有一个数组arr,那么arr[0]就是数组的第一个元素,arr[1]就是数组的第二个元素,0和1就是这个数组的key
var arr = [2, 4, 6, 8];
var {
0:a,
1:b,
[arr.length - 1]:d,
[arr.length - 2]:c
}= arr;
a; //2
b; //4
c; //6
d; //8
但相反情况下,是不可以的。
var obj = {
0: 1,
1: 2
}
var [a,b] = obj; //Uncaught TypeError: undefined is not a function
8. 默认值
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var {x: y = 3} = {};
y // 3
var {x: y = 3} = {x: 5};
y // 5
var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"
默认值生效的条件是,对象的属性值严格等于undefined
。
var {x = 3} = {x: undefined};
x // 3
var {x = 3} = {x: null};
x // null
字符串的解构赋值
字符串解构赋值 , 可以看作类似数组的对象
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "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
默认值
function add({x=10, y=20}) {
return x + y;
}
add({x: 1, y: 2}); //3
add({x: 1}); //21
add({}); //30
解构赋值的用途
1. 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
2. 从函数返回多个值
// 返回一个数组
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
3. 函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
4. 提取 JSON 数据
解构赋值对提取 JSON 对象中的数据,尤其有用。
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
5. 函数参数的默认值
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
} = {}) {
// ... do stuff
};
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';
这样的语句。
6. 遍历 Map 结构
const map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world
如果只想获取键名,或者只想获取键值,可以写成下面这样。
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
7. 输入模块的指定方法
加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。
const { SourceMapConsumer, SourceNode } = require("source-map");
还没有评论,来说两句吧...