title: ES6 学习笔记 - Destructing
date: 2021-02-01 17:23:22
tags: 技术
解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,者被称为解构(Destructing)
数组的解构赋值
基本用法
var[a,b,c] = [1,2,3];
let[ , , third] = ["foo","bar","baz"];
let[x, , y] = [1,2,3];
let[head,...tail]=[1,2,3,4];
let[x,y,...z] = ['a'];
如果解构不成功,变量的值就等于undefined
Set
对于Set结构,也可以使用数组的解构赋值
let[x,y,z] = new Set(["a","b","c"])
指定默认值
[x,y='b'] = ['a']; // x='a',y='b'
[x,y='b'] = ['a',undefined]; //x='a' ,y='b'
如果不===
undefined,默认值是不会生效的
var [x = 1] = [null];
x //null
因为null不是严格等于undefined ,所以默认值不生效
惰性求值
function f(){
console.log('aaa');
}
let [x=f()]=[1];
因为x能够取到值,所以函数f不会执行
对象的解构赋值
解构不仅可以用于数组,还可以用于对象
var {foo,bar} = { foo:"aaa", bar:"bbb"};
console.log(foo);//"aaa"
console.log(bar);//"bbb"
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。对象的解构赋值的内部机制,是先找到同名的属性,然后再赋给对应的变量。
var {foo:baz} = {foo:"aaa",bar:"bbb"};
console.log(baz);//aaa
console.log(foo);//foo is not defined
解构嵌套的对象
var obj = {
p:[
"Hello",
{y:"World"}
]
};
var {p:[x,{y}]} = obj;
console.log(x);
console.log(y);
声明过变量易错点
对于已经声明了的变量解构赋值,要非常小心
//BAD DEMO
var x;
{x} = {x:1};
报错原因,把{x}
理解成了一个代码块,从而发生语法错误,只有不把大括号写再行首,才能解决
//GOOD DEMO
var x;
({x} = {x:1});
字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转化成了一个类似数组的对象
const [a,b,c,d,e] = 'hello';
类似数组的对象都有个length属性,因此可以对这个属性解构赋值
let {length :len } = 'hello'
数值和布尔值的解构赋值
解构赋值的时候,如果等号右边的是数值和布尔值,会先转换成对象
let {toString :s} = 123;
s === Number.prototype.toString; //true
let {toString :s} = true;
s === Number.prototype.toString; //true
数值和布尔值的包装对象都有toString属性,所以s能够取到值
由于null和undefined无法转换成对象,所以对他们解构赋值会报错
函数参数的解构赋值
function add([x,y]){
return x+y;
}
console.log(add([1,2]));
add的参数不是一个数组,而是通过解构得到的变量x和y
圆括号的使用
[(b)] = [3];//正确
({p:(d)}) = {});//正确
[(parseInt.prop)] = [3];//正确
首先都是赋值语句,而不是声明语句;其次他们的圆括号都不属于模式的一部分。
第一句模式是取第一个成员
第二句模式是p
第三句与第一句一样
用途
交换变量的值
[x,y]=[y,x];
函数返回多个值
//返回一个数组
function example(){
return [1,2,3];
}
var [a,b,c] = example();
//返回一个对象
function example(){
return {
foo:1;
bar:2;
};
}
var {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数据
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
}){
//...
}
遍历Map结构
var 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");