ES6解构赋值
什么是解构赋值
解构赋值是对赋值运算符的扩展。
解构赋值允许你使用类似数组或对象字面量的语法将数组和对象的属性赋给各种变量。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
{
let a, b, rest;
[a, b] = [1, 2];
console.log('a:',a,'b:',b);
//a:1 b:2
}
默认值
ES6内部使用严格相等运算符’===’,判断一个位置是否有值。
所以,右侧数组成员不严格等于undefined,默认值是不会生效的。
右侧为null,也会赋值为null。
//默认值 场景:变量交换
{
let a, b, c;
//给c设置默认值'='
[a, b, c = 3] = [1, 2];
console.log('a:',a,'b:', b,'c:', c);
//a: 1 b: 2 c: 3
}
{
let a, b, c;
//给c设置默认值
[a, b, c = 3] = [1, 2 ,4];
console.log('a:',a,'b:', b,'c:', c);
//a: 1 b: 2 c: 4
}
数组解构赋值
- 数组解构赋值语法的一般形式为
[ variable1, variable2, …, variableN ] = array;
或者使用es6的语法:[…rest] = array;- 等号的右边必须是数组。
- 如果解构不成功,变量的值就等于undefined。
//...rest转为数组
{
let a, b, rest;
[a, b, ...rest] = [1, 2, 3, 4, 5, 6]
console.log('a:',a,' b:',b,' rest',rest);
//a: 1 b: 2 rest (4) [3, 4, 5, 6]
}
对象解构赋值
变量必须与属性同名。
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
为单个属性名赋值。
//示例3:
//对象赋值
{
let { a, b } = { a: 1, b: 2 };
console.log('a:',a,' b:',b);
//a: 1 b: 2
}
{
let c = {a,b};
c = {a:1,b:2};//找不到对应的同名属性
console.log('c:',c);
//a is not defined
}
{
let {a,b} = {a:{a:1,b:2},b:2};//找不到对应的同名属性
console.log('a:',a);
//a a: {a: 1, b: 2}
}
//对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
{
let {a:c,b:d} = {a:1,b:2};
console.log('c:',c,'d:',c);
//c: 1 d: 1
}
{
let c = {a:1,b:2};
let {a,b} = c;
console.log('a:',a,' b:',b);
//a: 1 b: 2
}
//let 重复定义
{
let foo;
let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"
let baz;
let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz"
}
//解析器会将起首的大括号,理解成一个代码块,而不是赋值语句。
{
let foo;
({foo} = {foo: 1}); //成功 块作用域
let baz;
({bar: baz} = {bar: 1}); //成功 块作用域
}
对象解构使用场景
{
//后端返回值
let metaDate = {
title: 'abc',
test: [{
title: 'test',
desc: 'description'
}]
};
//前端对应获取值,赋值给ftitle 和 ctitle。
let { title: ftitle, test: [{ title: ctitle }] } = metaDate;
console.log(ftitle, ctitle);
}
字符串解构赋值
//数组赋值
{
var [a,b,c,d,e,f] = 'hello';
console.log(a,b,c,d,e,f);
//h e l l o undefined
}
//对象返回长度
{
//类似数组的对象都有一个length属性。
//length 属性为类数组的长度。
//字符串会先赋值,生成类数组,类数组含有length,然后返回length值。
//len = 'hello'.length
let {length : len} = 'hello';
console.log(len)// 5
}
数值和布尔值解构赋值
{
//123 转为对象 Number
//Numer 找 toString;因为原型链上有toString,所以
//s 为Number.prototype.toString
let {toString: s} = 123;
s === Number.prototype.toString // true
//s() Number.prototype.toString requires that 'this' be a Number,意味着直接转为包装类了。
//true 转为Boolen
let {toString: s} = true;
s === Boolean.prototype.toString // true
}
set解构赋值
{
let setV = new Set(["a", "b", "c"]);
let [x, y, z] = setV ;
console.log(x,y,z);//a b c
}
函数参数解构赋值
//示例1
{
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
//[x,y] = [1, 2]
}
//示例2
{
[[1, 2], [3, 4]].map(([a, b]) => a + b);//[3,7]
//遍历[a,b] = [1, 2],[a,b] = [3, 4]
}
//示例3,配合默认使用
{
//传对象{x, y}
//x y不传是0
//什么都不传默认是{}
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]
}
Iterator解构赋值
数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
{
//Generator 函数
function* fibs() {
var a = 0;
var b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
};
//创建fibs对象实例
//a = fibs().next().value;
//其中:fibs().next()返回{value: 0, done: false}既Iterator返回值。
var [a, b, c, d, e, f] = fibs();
console.log(a, b, c, d, e, f) // 0 1 1 2 3 5
}
使用括号
赋值语句的非模式部分,可以使用圆括号。
[(b)] = [3]; // 正确 b赋值
({ p: (d) } = {}); // 正确 d是赋值
[(parseInt.prop)] = [3]; // 正确 (parseInt.prop)整体赋值
用途
交换变量值
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});
函数参数的默认值
jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
} = {}) {
// ... do stuff
};
遍历 Map 结构
//[key, value]
for (let [key, value] of map) {
console.log(key + " is " + value);
}
输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
//"source-map"抛出来的是对象