es6-2 (变量的解构赋值)
本文以及之后的文章都是参考
阮一峰ES6入门
,记录下作为笔记。
数组的解构赋值
对象的解构赋值
字符串的解构赋值
数值和布尔值的结构赋值
函数参数的结构赋值
圆括号问题
用途
1 .数组的解构赋值
let a = 1;
let b = 2;
let c = 3;
ES6允许写成下面这样
let [a, b, c] = [1, 2, 3];
eg:
let[x,y,...z] = ['a']
x // "a"
y // "undefined"
z // []
如果解构不成功,变量的值就等于undefined.
事实上,子要某种数据结构具有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
上面代码中,fibs是一个Generator函数,原生具有Iterator接口,解构赋值回一次从这个接口获取值。
默认值
let[x=1] = [undefined];
x //1
let [x = 1] = [null]
x //null
上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined
如果默认值是一个表达式,那么这个表达式是惰性求值,即只有在用到的时候,才会求值。
function f(){
console.log('aaa')
}
let [x=f()] = [1]
上面代码中,因为x能取到值,所以函数f根本不会执行,上面的代码其实等价于下面的代码。
let x;
if([1][0] === undefined){
x = f()
}else{
x = [1][0]
}
默认值可以引用结构赋值的其他变量,但该变量必须已经声明。
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError
上面最后一个表达式之所以回报错,是因为x用到默认值y时,y还没有声明
对象的结构赋值
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
对象的黑狗与数组有一个重要的不同,数组的元素是俺次序排列的,变量的取值由它的未知决定,而对象的属性没有次序,变量必须与属性同名,才能渠道正确的值
let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined
也就是说,对象的结构赋值的内部机智,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者
与数组一样,结构也可以用于嵌套结构的对象。
let obj = {
p:[
'hello',
{y:'world'}
]
}
let {p:[x,{y}]} = obj;
console.log(x+' '+y);
console.log(obj.p[0]);
console.log(obj.p[1].y);
对象的解构也可以指定默认值。
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"
如果要将一个已经声明的变量用于解构赋值,必须非常小心
函数的参数的解构赋值
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]
注意下面的写法会得到不一样的结果
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]
上面代码是为函数move的桉树指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。
undefined就会触发函数参数的默认值。
let arr = [1,undefined,4];
arr.map((x = 'yes')=>{
console.log(x);
})
圆括号问题。
解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。
由此带来的问题是,如果模式中出现圆括号怎么处理。ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。
但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号。
用途。
- 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
- 从函数返回多个值
// 返回一个数组
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
-
函数参数的定义
// 参数是一组有次序的值 function f([x, y, z]) { ... } f([1, 2, 3]); // 参数是一组无次序的值 function f({x, y, z}) { ... } f({z: 3, y: 2, x: 1});
-
提取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]
-
函数参数的默认值
jQuery.ajax = function (url, { async = true, beforeSend = function () {}, cache = true, complete = function () {}, crossDomain = false, global = true, // ... more config }) { // ... do stuff };
-
遍历Map结构
const map = new Map(); map.set('first', 'hello'); map.set('second', 'world'); for (let [key, value] of map) { console.log(key + " is " + value); }
如果只想获取键名,或者只想获取键值,可以写成下面这样。
// 获取键名 for (let [key] of map) { // ... } // 获取键值 for (let [,value] of map) { // ... }
-
输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
网友评论