19

完全搞懂 Javascript 中的... [每日前端夜话0xE3]

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzI3NzIzMDY0NA%3D%3D&%3Bmid=2247487683&%3Bidx=1&%3Bsn=24b71d885df01569469f0d7276baf0f5
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

每日前端夜话 0xE3

每日前端夜话,陪你聊前端。

每天晚上18:00准时推送。

正文共:3509 字

预计阅读时间:8 分钟

作者:Gábor Soós

翻译:疯狂的技术宅

来源: dev.to

vaUBvyI.png!web

曾几何时,ES6/ES2015 对 Javascript 语言进行了重大升级。它引入了许多不同的新功能。其中之一就是我们可以用在任何兼容容器(对象、数组、字符串、集合、映射)前面的三个连续点。这些小点使我们能够编写更加优雅和简洁的代码。在本文中我将会解释这三个点的工作原理,并展示最常见的例子。

三个连续的点具有两个含义:展开运算符(spread operator)和剩余运算符(rest operator)。

展开运算符

展开运算符允许迭代器在接收器内部分别展开或扩展。迭代器和接收器可以是任何可以循环的对象,例如数组、对象、集合、映射等。你可以把一个容器的每个部分分别放入另一个容器。

1const newArray = ['first', ...anotherArray];

剩余参数

剩余参数语法允许我们将无限数量的参数表示为数组。命名参数的位置可以在剩余参数之前。

1const func = (first, second, ...rest) => {};

用例

定义是非常有用的,但是很难仅从定义中理解概念。我认为用日常用例会加强对定义的理解。

复制数组

当我们需要修改一个数组,但又不想改变原始数组(其他人可能会使用它)时,就必须复制它。

1const fruits = ['apple', 'orange', 'banana'];
2const fruitsCopied = [...fruits]; // ['apple', 'orange', 'banana']
3
4console.log(fruits === fruitsCopied); // false
5
6// 老方法
7fruits.map(fruit => fruit);

它正在选择数组中的每个元素,并将每个元素放在新的数组结构中。我们也可以使用 map 操作符实现数组的复制并进行身份映射。

唯一数组

如果我们想从数组中筛选出重复的元素,那么最简单的解决方案是什么?

Set 对象仅存储唯一的元素,并且可以用数组填充。它也是可迭代的,因此我们可以将其展开到新的数组中,并且得到的数组中的值是唯一的。

1const fruits = ['apple', 'orange', 'banana', 'banana'];
2const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana']
3
4// old way
5fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);

串联数组

可以用 concat 方法连接两个独立的数组,但是为什么不再次使用展开运算符呢?

1const fruits = ['apple', 'orange', 'banana'];
2const vegetables = ['carrot'];
3const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
4const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']
5
6// 老方法
7const fruitsAndVegetables = fruits.concat(vegetables);
8fruits.unshift('carrot');

将参数作为数组进行传递

当传递参数时,展开运算符能够使我们的代码更具可读性。在 ES6 之前,我们必须将该函数应用于 arguments 。现在我们可以将参数展开到函数中,从而使代码更简洁。

1const mixer = (x, y, z) => console.log(x, y, z);
2const fruits = ['apple', 'orange', 'banana'];
3
4mixer(...fruits); // 'apple', 'orange', 'banana'
5
6// 老方法
7mixer.apply(null, fruits);

数组切片

使用 slice 方法切片更加直接,但是如果需要的话,展开运算符也可以做到。但是必须一个个地去命名其余的元素,所以从大数组中进行切片的话,这不是个好方法。

1const fruits = ['apple', 'orange', 'banana'];
2const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']
3
4// 老方法
5const remainingFruits = fruits.slice(1);

将参数转换为数组

Javascript 中的参数是类似数组的对象。你可以用索引来访问它,但是不能调用像 mapfilter 这样的数组方法。参数是一个可迭代的对象,那么我们做些什么呢?在它们前面放三个点,然后作为数组去访问!

1const mixer = (...args) => console.log(args);
2mixer('apple'); // ['apple']

将 NodeList 转换为数组

参数就像从 querySelectorAll 函数返回的 NodeList 一样。它们的行为也有点像数组,只是没有对应的方法。

1[...document.querySelectorAll('div')];
2
3// 老方法
4Array.prototype.slice.call(document.querySelectorAll('div'));

复制对象

最后,我们介绍对象操作。复制的工作方式与数组相同。在以前它可以通过 Object.assign 和一个空的对象常量来实现。

1const todo = { name: 'Clean the dishes' };
2const todoCopied = { ...todo }; // { name: 'Clean the dishes' }
3console.log(todo === todoCopied); // false
4
5// 老方法
6Object.assign({}, todo);

合并对象

合并的唯一区别是具有相同键的属性将被覆盖。最右边的属性具有最高优先级。

1const todo = { name: 'Clean the dishes' };
2const state = { completed: false };
3const nextTodo = { name: 'Ironing' };
4const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false }
5
6// 老方法
7Object.assign({}, todo, state, nextTodo);

需要注意的是,合并仅在层次结构的第一级上创建副本。层次结构中的更深层次将是相同的引用。

将字符串拆分为字符

最后是字符串。你可以用展开运算符把字符串拆分为字符。当然,如果你用空字符串调用 split 方法也是一样的。

1const country = 'USA';
2console.log([...country]); // ['U', 'S', 'A']
3
4// 老方法
5country.split('');

总结

在本文中我们研究了 Javascript 中展开运算符的许多用例。如你所见,ES6 不仅使编写代码的效率更高,而且还引入了一些有趣的方法来解决长期存在的问题。现在所有主流浏览器都支持新语法。在你阅读本文时,就可以在浏览器的控制台中尝试上述所有例子。无论用哪种方式,你现在就可以把展开运算符和剩余参数用到自己的代码中。

原文: https://dev.to/blacksonic/the-tale-of-three-dots-in-javascript-4287

下面夹杂一些私货:也许你和高薪之间只差这一张图

2019年京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。

愿你有个好前程,愿你月薪30K。我们是认真的 ! BbquyaF.png!web

zMFVruu.jpg!web

在公众号内回复“体系”查看高清大图

长按二维码,加大鹏老师微信好友

拉你加入前端技术交流群

唠一唠怎样才能拿高薪

JFNJFbv.jpg!web

小手一抖,资料全有。长按二维码关注 前端先锋 ,阅读更多技术文章和业界动态。

MFryQjN.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK