JavaScript 学习笔记:ES6 新特性 — 解构赋值、展开语法、剩余参数


ES6 泛指 5.1版以后的下一代 JS标准。涵盖 ECMAScript 2015、ECMAScript 2016、ECMAScript 2017
其中 15是正式版 16,17只是在 15基础上的补丁。

一、解构赋值

1、解构数组

1.1 语法

var arr = [1 , 2];
var [a, b] = arr;
console.info(a, b); // 1 2

1.2. 示例

1.2.1. 交换变量

js终于也支持这种语法了

var x = 1, y = 2;
[x, y] = [y, x];
console.info(x, y); // 2 1
1.2.2. 丢掉一部分变量

如果函数返回一个数组,外面有需要从数组中取元素来赋值,这个就方便了。

var [a, , , d] = [1, 2, 3, 4];
console.log(a); // 1
console.log(d); // 4
1.2.3. 默认值
// 有值直接取
var [a, b='B', c='C', d] = [1, 2, 3, 4];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // 4
// 无值用默认
var [a, b='B', c='C', d] = [1, , , 4];
console.log(a); // 1
console.log(b); // B
console.log(c); // C
console.log(d); // 4
// undefined 也当无值。但null不能触发默认值,因为null是一个值
var [a, b='B', c='C', d] = [1, undefined, undefined, 4];
console.log(a); // 1
console.log(b); // B
console.log(c); // C
console.log(d); // 4

2、解构对象

左边用key 当变量,接受右边对象中对应key的值

2.1. 语法

2.1.1. 基本语法
  • 解构并赋值给新变量
var obj = {a:1 , b:2};
var {a, b} = obj ; // 声明了a, b 两全局变量
console.info(a, b); // 1 2
  • 用已有变量接收值
    上面的语法有个缺陷,我们并不总是要创建新变量,有时只是想用已有变量,接收值。
var obj = {a:1, b:2, c:3};
var a, b, c;
( {a, b, c} = obj );
console.log(`a=${a}, b=${b}, c=${c}`); // a=1, b=2, c=3
  • 用另一个对象接收
    如果我们想将对象1的部分属性,复制给对象2,则还需要结合 2.1.4 的改名规则。
var obj1 = { a: 1, b: 2, c: 3 };
var obj2 = { a: 666, c: 999};
({a: obj2.a, c: obj2.c} = obj1);
console.log(obj2); // 输出:{ a: 1, c: 3 }
var sources = {a:1, b:2, c:3, d:4}; // 源
var {a, b, c} = {...sources};// 提取指定属性
var target = {a, b, c};   // 创建新对象
console.log(target); // 输出:{a: 1, b: 2, c: 3}
2.1.2. 多层嵌套对象解构

对象还包含对象。。。(听上去是一个悲伤的故事2333333)

var obj = {
	a: '奔波儿灞' ,
	b: '霸波尔奔',
	npc:{ name : '龙王'}
};
var {a , b, npc:{name} } = obj;

console.info(a); // 奔波儿灞
console.info(b); // 霸波尔奔
console.info(npc); //npc is not defined
console.info(name); //龙王
2.1.3. 混合嵌套

对象跟数组混着套来套去。

var obj = {
	a: '奔波儿灞' ,
	b: '霸波尔奔',
	npc: [1, 2, 3, 4]
};
var {a , b, npc:[n1, n2, n3, n4] } = obj;

console.info(a); // 奔波儿灞
console.info(b); // 霸波尔奔
console.info(n1); // 1
console.info(n2); // 2
console.info(n3); // 3
console.info(n4); // 4
2.1.4. 声明新变量 (换名字)

当原对象的key名字不符合我们要求时,可以如下操作,实现改名。
解构后得到新变量 npc1、npc2

var obj = {a: '奔波儿灞' , b: '霸波尔奔'};
var {a: npc1, b: npc2} = obj ; // 从 obj.a 取值赋给 npc1, 从 obj.b 取值赋给 npc2
console.info(npc1, npc2); // 奔波儿灞 霸波尔奔

2.4. 函数参数解构

function foo({npc, npcLoc, hp }){
  console.log(npc, npcLoc, hp);
}
foo({npc:'奔波儿灞', npcLoc:{ x: 0, y: 0}, hp:99 }); 

将数组展开成单个参数,与Function.prototype.apply()效果相同 。

((a,b,c)=>{
    console.log(a,b,c);
})(...['龙王','奔波儿灞','霸波尔奔']);
((a,b,c)=>{
    console.log(a,b,c);
}).apply(null, ['龙王','奔波儿灞','霸波尔奔']);
2.4.1 参数默认值
  • 基本类型
function test(str = "大家好,我是笨笨,笨笨的笨,笨笨的笨,谢谢!", n = 123){
    console.log(str);
    console.log(n);
}
  • 对象
function foo(options = {}){
	let {npc = '霸波尔奔', npcLoc = { x: 9527, y: 2046 }, hp = 10000} =  options;
	console.log(npc, npcLoc, hp);
}
foo(); // 霸波尔奔 {x: 9527, y: 2046} 10000
foo({npc:'奔波儿灞', npcLoc:{ x: 0, y: 0}}); // 奔波儿灞 {x: 0, y: 0} 10000
  • 对象(简写)
function foo({npc = '霸波尔奔', npcLoc = { x: 9527, y: 2046 }, hp = 10000} = {}){
  console.log(npc, npcLoc, hp);
}

3. 属性简写

字面量中,keyvalue 相同时时可以简写。(以后声明方法时经常用。)

var a = 1, b = 2;
var obj = { a : a, b : b}; // 完整写法
var obj1 = {a, b};			// 简写
JSON.stringify(obj,null,0) === JSON.stringify(obj1,null,0); // true

当然函数也可以当属性,所以:

var obj = { 
	fun(){
		console.log(666);
	}
};
obj.fun(); // 666

二、展开语法

let [... arr] = [ 1,2,3,4 ]; // 接收时的效果是收集进数组。
let [a,b,c,d] = [... arr]; // 赋值时的效果是展开成多个。

函数调用

// 为了演示先定义个函数
function foo(a,b,c){
	console.info('第一个参数: ' + a);
	console.info('第二个参数: ' + b);
	console.info('第三个参数: ' + c);
}
// 这是我们为它准备的实参
var arr = ['666','999','9527'];
// 在以前是这样实现的
foo.apply(null, arr);
// 利用展开语法的写法
foo(...arr);

new新对象时

显然 apply 虽好,但在new新对象的时候就没那么好用了。有了展开语法可以结局这个尴尬

  • 数组去重
var result = [...new Set([1,1,2,2,3,3,4,4])];
console.info(result);// [1, 2, 3, 4]
// 分解步骤
var arr = [1,1,2,2,3,3,4,4];
var myset = new Set(arr);// 实际去重是利用集合元素不重复的特性实现的
var result = [...myset];
console.info(result);// [1, 2, 3, 4]

创建时间对象

new Date(...[2019,10,05]);
new Date(..."2019-10-05".split("-"));
new Date("2019-10-05");

字面量数组

值得注意的是这种展开是一种浅复制(只遍历一层),如果多为嵌套就要小心了。不然会无意间修改到原始对象。

// 直接展开来用
var a = [1,2,3], b = [4,5,6];
var arr = [...a, ...b];
console.info(arr);// [1, 2, 3, 4, 5, 6]
// 还可以反反复复用
var arr = [...a, ...b, ...a];
console.info(arr);// [1, 2, 3, 4, 5, 6, 1, 2, 3]

字面量对象

在数组或函数参数中使用展开语法时, 该语法只能用于 可迭代对象。
下面的例子很像 jQuery$.extend 合并对象

var obj1 = { 'year': '2019', 'month': '10' };
var obj2 = { 'year': '2020', 'day': '05' };
var obj3 = {...obj1, ...obj2};
// year 有两个,后面的替换了前面的。 month 和 day 只有一个,都直接留下了。
console.info(obj3);// {year: "2020", month: "10", day: "05"}
// 浅复制没问题,但不支持深度复制。
obj3.year = "2046";
obj3.month = "12";
obj3.day = '31';
console.info(obj3);// {year: "2046", month: "12", day: "31"}
console.info(obj1);// {year: "2019", month: "10"}
console.info(obj2);// {year: "2020", day: "05"}

三、组合使用

数组套对象

var [name, { msg}] = ['笨笨', { msg: '大家好,我是笨笨,笨笨的笨,笨笨的笨,谢谢!' }];
console.log(`name: "${name}", msg: "${msg}"`);
// name: "笨笨", msg: "大家好,我是笨笨,笨笨的笨,笨笨的笨,谢谢!"

剩余参数

其余参数封装进一个数组里,这个是针对 arguments 说的。

// 为了演示先定义个函数
function foo(a,b,c,...arr){
	console.info('第一个参数: ' + a);
	console.info('第二个参数: ' + b);
	console.info('第三个参数: ' + c);
	console.info('其余参数封装进一个真数组里' + Array.isArray(arr) + ': ' + arr);
}
foo(1,2,3,4,5,6,7,8,9);
/*
第一个参数: 1
第二个参数: 2
第三个参数: 3
其余参数封装进一个真数组里true: 4,5,6,7,8,9
*/

Object 对象映射

源对象中指定keyvalue赋值给目标对象的指定key

/**
 * 对象映射
 * 
 * @param {Object} source	源对象
 * @param {Array} keys		源对象的key
 * @param {Object} dist		目标对象
 * @param {Array} keys2		目标对象的key
 */
function objMapping(source, keys, dist = {}, keys2 = keys){
    return keys.reduce((a,c,i) => Object.assign(a, {[keys2[i]]:source[c]}) , dist);    
}

objMapping({a:1, b:2, c:3}, ["a", "b"],  {aa:11, bb:22, cc: 33});
// {aa: 11, bb: 22, cc: 33, a: 1, b: 2}
objMapping({a:1, b:2, c:3}, ["a", "b"],  {aa:11, bb:22, cc: 33}, ["aa", "cc"]);
// {aa: 1, bb: 22, cc: 2}

参考资料

解构赋值 Destructuring_assignment
展开语法 Spread syntax
剩余参数 Rest_parameters
阮一峰 Blog:变量的解构赋值

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值