介绍

Rest 和 Spread 的共同点是语法都是 ... (点点点). 但它们的概念是相反的. 看例子体会:

Rest Parameters

参考: 阮一峰 – rest 参数

rest parameters 可以替代 arguments 对象.

old school:

function method(v1, v2, v3) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
console.log(arguments[3]); // 4
console.log(arguments.length); // 4
console.log(Array.isArray(arguments)); // false
// arguments is iterable
for (const arg of arguments) {
console.log('arg', arg);
}
} method(1, 2, 3, 4);

modern:

function method(...args) {
console.log(Array.isArray(args)); // true
}
method(1, 2, 3, 4);

除了它是 array 以外, 其它都和 arguments 一样,

left arguments

除了可以取代 arguments 对象, 它还可以更灵活.

function method(firstArg, ...leftArgs) {
console.log(firstArg); // 1
console.log(leftArgs); // [2, 3, 4]
}
method(1, 2, 3, 4);

直接把 arguments 拆成  2 组, 是不是很方便?

注: rest parameters 只能放到最后一个 parameter 哦, 下面这样放中间是不行的哦

use in destructuring assignment

const [v1, ...others] = [1, 2, 3, 4];

和 left arguments 同个概念, 只是用在 destructuring assignment 上. (rest 依然必须在最后一个哦)

解构对象也是可以的

const { name, ...leftProperties } = { name: 'Derrick', age: 11 };
console.log(leftProperties.age); // 11

Spread Operator

参考:

阮一峰 – 数组扩展运算符

阮一峰 – 对象扩展运算符

spread operator 可以用在 array 和 object 上, 先看看 array 的用法.

spread array to parameters

function method(a, b, c) {}

method(1, 2, 3);
method(...[1, 2, 3]);
method(1, ...[2, 3]);

rest parameters 是把多个值 combine 到一个 array 里. spread operator 有点相反的味道.

它把一个 array 拆成多个 parameters 输入.

spread array fill into array

const array1 = [1, 2, 3];
const array2 = [...array1, 4, 5]; // [1, 2, 3, 4, 5]

array1 被拆成一个一个放入新的 array 中.

如果 array 是空的, 那什么也不会发生.

const array3 = [...[], 4, 5]; // [4, 5]

spread object fill into object

这个是 ES2018 才有哦.

和 fill into array 玩法一样

const obj1 = { age: 11 };
const obj2 = {
name: 'Derrick',
age: 10,
...obj1,
level: 50,
};
// obj2 = { name: 'Derrick', age: 11, level: 50 }

obj1.age 11 覆盖掉了原本的 obj2.age 10, 上面这个写法和 Object.assign 是等价的哦.

小心 undefined

const obj1 = {
name: undefined,
}; const obj2 = {
name: 'Derrick',
...obj1,
}; console.log(obj2.name); // undefined

Object.assign 也会这样哦. 所以要特别小心. 有 2 个解决方法:

第一是针对属性做判断

const obj1 = {
name: undefined,
}; const obj2 = {
name: 'Derrick',
...(obj1.name !== undefined ? { name: obj1.name } : undefined),
};
console.log(obj2.name); // 'Derrick'

当 obj1.name 有值就变成 ...{ name: obj1.name } 不然就是 ...undefined, 然后 undefined 会被强转成 empty object 最终就是 ...{} 啥也没有就抵消掉了.

另一个方法是自己封装一个 Object.Assign, 自己 loop key 检查是否是 own property 才 override.

总结

Rest Parameters 像 "收", 把多个值收集到一个 array 或 object 中.

Spread Operator 像 "放" 把 array 或 object 里的值, 释放开来.

可以同时 "放" 多个, 但是不能 "收" 多个.

const a = [1, 2];
const b = [4, 5];
const c = [...a, 3, ...b]; // 同时释放 2 个 const [...a, 3, ...b] = [1, 2, 3, 4, 5]; // error! 同时收 2 个是不可以的 (因为它不知道要 combine 多少个丫)

JavaScript – Rest Parameters & Spread Operator的更多相关文章

  1. JavaScript展开操作符(Spread operator)介绍

    本文介绍JavaScript的展开操作符(Spread operator)....本文适合ES6初学者. 你可以通过展开操作符(Spread operator)...扩展一个数组对象和字符串.展开运算 ...

  2. JavaScript剩余操作符Rest Operator

    本文适合JavaScript初学者阅读 剩余操作符 之前这篇文章JavaScript展开操作符(Spread operator)介绍讲解过展开操作符.剩余操作符和展开操作符的表示方式一样,都是三个点 ...

  3. 《理解 ES6》阅读整理:函数(Functions)(三)Function Constructor & Spread Operator

    增强的Function构造函数(Increased Capabilities of the Function Constructor) 在Javascript中Function构造函数可以让你创建一个 ...

  4. [ES6] 13. Using the ES6 spread operator ...

    The spread operator (...) allows you to "explode" an array into its individual elements. S ...

  5. [ES6] 23. Rest Parameters & Spread Parameters

    Rest Parameters: In ES5, when you don't know how many paramters will be passed in, you can use argum ...

  6. [译]Javascript中的Ternary operator

    本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...

  7. [Python] Object spread operator in Python

    In JS, we have object spread opreator: const x = { a: '1', b: '2' } const y = { c: '3', d: '4' } con ...

  8. [ES6系列-06]展开操作符 Spread Operator 就像解压到这里

    [原创]码路工人 Coder-Power 大家好,这里是码路工人有力量,我是码路工人,你们是力量. github-pages 博客园cnblogs 在前面的文章中,介绍了...在获取剩余参数中的作用. ...

  9. [ES6] ... spread operator

    var parts = ['shoulders', 'knees']; var lyrics = ['head', ...parts, 'and', 'toes']; // ["head&q ...

  10. 现在就可以使用的5个 ES6 特性

    小编推荐:掘金是一个高质量的技术社区,从 ECMAScript 6 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货.各大应用市场搜索「掘金」即可下载APP,技术干货尽在掌握. ...

随机推荐

  1. 从基础到高级应用,详解用Python实现容器化和微服务架构

    本文分享自华为云社区<Python微服务与容器化实践详解[从基础到高级应用]>,作者: 柠檬味拥抱. Python中的容器化和微服务架构实践 在现代软件开发中,容器化和微服务架构已经成为主 ...

  2. vuex使用和场景案例

    vuex是vue提供的一个集中式状态管理器,用于对数据的集中式管理. vuex有四个重要的属性:state.mutations.actions.getters 1.vuex的使用 安装 npm ins ...

  3. 网络基础 CAS协议学习总结

    架构介绍 系统组件 CAS服务器和客户端构成了CAS系统体系结构的两个物理组件,它们通过各种协议进行通信. CAS服务器 CAS服务器是基于Spring Framework构建的Java servle ...

  4. 题解:P9777 [HUSTFC 2023] Fujisaki 讨厌数学

    令 \(f(n)=x^{n}+x^{-n}\). 可以发现 \(f(n)f(m)=x^{n-m}+x^{m-n}+x^{n+m}+x^{-n-m}=f(n-m)+f(m+n)\). 若 \(m=1\) ...

  5. 【Java,IDEA】创建自己的代码模版快速生成

    写原生JavaWeb发现一个问题就是声明方法的时候没有字符关联提示, 只能一个保留字,一个保留字这样单个的敲出来方法,写多了就会发现特别费劲 当遇上一个字特别多且经常需要声明的方法可以使用IDEA的生 ...

  6. 为什么自动驾驶领域发论文都是用强化学习算法,但是实际公司里却没有一家使用强化学习算法?—— (特斯拉今年年初宣布推出实际上第一款纯端到端的自动驾驶系统,全部使用强化算法,替换掉30万行C++的rule-based代码)

    为什么自动驾驶领域发论文都是用强化学习算法,但是实际公司里却没有一家使用强化学习算法?-- (特斯拉今年年初宣布推出实际上第一款纯端到端的自动驾驶系统,全部使用强化算法,替换掉原有的30万行C++的r ...

  7. 【转载】 Tensorflow学习笔记-模型保存与加载

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/lovelyaiq/article/det ...

  8. linux终端如何加上时间,添加时间戳到终端提示?

    方法: 在 .bashrc 文件中加入: export PROMPT_COMMAND="echo -n \[\$(date +%H:%M:%S)\\] " 这样便可以在每次输入命令 ...

  9. gym.ActionWrapper使用时的注意点——step函数可以覆盖observation函数

    本文说的这个gym.ActionWrapper继承类的问题和gym.ObservationWrapper继承类的问题性质是一样的,具体看: gym.ObservationWrapper使用时的注意点- ...

  10. 说说中国高校理工科教育中的基础概念混乱问题——GPU是ASIC吗

    在YouTube上看到这样一个视频: https://www.youtube.com/watch?v=7EXDp6c9n-Q&lc=Ugydwl8gppB5FWE8Y5V4AaABAg.9fc ...