这篇文章的标题来自我在 Quora 上被要求回答的一个问题 http://qr.ae/TUNtnE . 下面是我试图解释 JavaScript 中三个点的作用. 希望这对于将来有相同问题的人来说可以消除围绕这个概念的迷雾.
数组 / 对象扩展运算符
假设您有以下对象:
- const adrian = {
- fullName: 'Adrian Oprea',
- occupation: 'Software developer',
- age: 31,
- website: 'https://oprea.rocks'
- };
假设您要创建一个具有不同名称和网站但具有相同职业和年龄的新对象(人).
您可以通过仅指定所需的属性来执行此操作, 并使用扩展运算符来完成其余操作, 如下所示:
- const bill = {
- ...adrian,
- fullName: 'Bill Gates',
- website: 'https://microsoft.com'
- };
上面代码的作用是遍布 adrian 对象并获取其所有属性, 然后用我们传递的属性覆盖现有属性. 可以将这种传播视为逐个提取所有单个属性并将它们传递给新对象.
在这种情况下, 由于我们在扩展运算符启动后指定了 fullName 和网站属性, 因此 JavaScript 引擎知道我们要覆盖来自原始对象的那些属性的原始值.
这与阵列类似. 除了传播键和值之外, 运算符不会传播索引 (index) 和值. 与对象传播不同的是, 你不会有重复的属性, 因为这是 JavaScript 对象的工作方式(你不能拥有一个具有两个 fullName 属性的对象), 如果你计划实现类似的东西, 那么对于数组你最终可能会有重复的值到我们的对象示例.
这意味着下面的代码将导致您拥有包含重复元素的数组.
- const numbers1 = [1, 2, 3, 4, 5];
- const numbers2 = [ ...numbers1, 1, 2, 6,7,8]; // this will be [1, 2, 3, 4, 5, 1, 2, 6, 7, 8]
可以把它想象成 Array.prototype.concat https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat 的替代品.
rest 运算符
使用函数的参数时, 无论是完全替换参数还是与函数的参数一起替换参数, 这三个点也称为 rest 运算符.
当像这样使用它时, rest 操作符使开发人员能够创建可以获取无限数量的参数的函数, 也称为变量 arity 或可变函数.
这是这种功能最简单的例子. 假设您要创建一个计算其所有参数之和的函数. 请注意, 它不是两个, 三个或四个数字的总和, 而是函数作为参数接收的所有数字的总和.
这是一个简单的实现, 使用 rest 运算符
- function sum(...numbers) {
- return numbers.reduce((accumulator, current) => {
- return accumulator += current
- });
- };
- sum(1,2) // 3
- sum(1,2,3,4,5) // 15
最简单的解释是, rest 运算符接收函数接收的参数并将它们转储到以后可以使用的实数数组中.
你可能会觉得, 你可以通过请求用户传递一组数字来完成此操作. 这在技术上是可行的, 但是这样的用户体验很差, 因为用户希望用普通数字而不是数字列表来调用 sum 函数.
您可能还认为可以使用 arguments 数组. 这也是事实, 但要小心, 参数不是真正的数组, 而是类似数组的对象(具有 length 属性的对象). 对于我们的 sum 函数的第一次调用, 在前面的例子中, 它实际上看起来像这样:
- {
- '0': 1,
- '1': 2,
- 'length': 2
- }
要操作此对象并在其上使用数组方法, 例如 reduce, 从我之前的示例中, 您必须执行 Array.prototype.slice.call(arguments,0)操作. 就速度和内存使用而言, 这表现不佳并且不优雅. 这样的代码, 容易让你的初级水平的同事感到困惑.
这应该是您需要了解的所有内容, 以便在 JavaScript 中使用 rest / spread 运算符.
如果您对如何改进文章有任何建议, 或者您需要一些帮助来围绕这个概念, 请在下面留言.
来源: https://juejin.im/entry/5b84a68351882542e16bfdb6