ES6学习-解构赋值
近期学习的ES6,关于解构赋值的部分。
基本用法
从数组和对象中提取值,对变量进行赋值,这称为解构
var [a, b, c] = [1, 2, 3];
如果解构不成功,变量的值就等于
undefined
另一种情况是不完全解构,部分变量赋值成功,部分不成功
Set结构也可以使用数组的解构赋值
某种数据结构具有
Iterator接口
,都可以采用数组形式的解构赋值
默认值
解构赋值允许指定默认值
var [foo = true] = []; // foo = true
如果一个数组成员不严格等于(===)undefined,默认值不会生效
默认值可以引用解构赋值的其他变量,但变量必须已经声明
对象的解构赋值
数组的元素是按次序排列的,变量的值由它的位置决定,而对象属性必须与变量同名,才能取到正确的值
如果变量名与属性不一致,必须写成下面的样子
let obj = {first: 'helo', last: 'world'};
let {first: f, last: l} = obj;
f // 'helo'
l // 'world'
- 也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者
采用这种写法时,变量的声明和赋值是一体的
对于
let
和const
来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错
let foo;
let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"
({foo} = {foo: 1}); // 成功;注意这里的大括号的必须的
字符串的解构赋值
const [a, b, c, d, e] = 'hello'
a // 'h'
b // 'e'
...
数值和布尔值的解构赋值
如果等号的右边是数值和布尔值,则会先转为对象
由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错
函数参数的解构赋值
function add([x, y]) {
return x + y;
}
add([1, 2]);
- 函数add参数表面上是一个数组,但是传入参数的那一刻,参数数组被解构成变量x和y。函数内部感受到的参数就是x和y
圆括号问题
- 对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。由此带来的问题是,如果模式中出现圆括号怎么处理。
只要有可能,就不要在模式中放置圆括号。
在变量声明语句中,不能带有圆括号
var [(a)] = [1];
函数参数中,模式不能带有圆括号
function f([(z)]) { return z;}
赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中
({ p: a }) = { p: 42 };
可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括
[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
首先它们都是赋值语句,而不是声明语句
其次它们的圆括号都不属于模式的一部分
用途
- 交换变量的值
[x, y] = [y, x];
- 从函数返回多个值
- 函数参数的定义
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
- 提取JSON数据
var jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number); // 42, "OK", [867, 5309]
- 函数参数的默认值
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
}) {
// ... do stuff
};
- 遍历Map结构
- 输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
- 输入模块的指定方法