JS 中的展开运算符你了解多少 ?

什么是展开运算符 (...)?

  • 展开运算符 :允许一个表达式在某处展开。展开运算符在多个参数(用于函数调用)或多个元素(用于数组字面量)或者多个变量(用于解构赋值)等地方可以使 用,作用就是 展开数组或字符串为一个新数组
  • 注意 : 展开运算符不能用在对象当中,因为目前展开运算符只能在可遍历对象(iterables)可用。iterables 的实现是依靠 [Symbol.iterator] 函数,而目前只有 Array,Set,String 内置 [Symbol.iterator] 方法,而 Object 尚未内置该方法,因此无法使用展开运算符。不过 ES7 草案当中已经加入了对象展开运算符特性。

怎么在函数调用中使用 ?

  • 在 ES6 之前,我们会使用 apply 方法将一个数组展开成多个参数 :
function test(a,b,c){/* code */}
var args = [0,1,2];
test.apply(null,args);
  • 上面代码,将 args 数组当作实参传递给了 a,b,c; 利用了 Function.prototype.apply 的特性。
  • 在 ES6 中,我们就可以更加简洁地来传递数组参数:使用 ...展开运算符就可以把 args 直接传递给 test() 函数。
function test(a,b,c){/* code */}
var args = [0,1,2];
test(...args);

怎么在数组字面量中使用 ?

  • 在 ES6 中,我们可以直接加一个数组直接合并到另外一个数组当中:
var arr1 = ['a','b','c'];
var arr2 = [...arr1,'d','e'];//['a','b','c','d','e']
  • 展开运算符也可以用在 push 函数中,可以不用再用 apply() / concat() 函数来合并两个数组:
var arr1 = ['a','b','c'];
var arr2 = ['d','e'];
arr1.push(...arr2);//['a','b','c','d','e']

怎么在解构赋值中使用 ?

  • 解构赋值也是 ES6 中的一个特性,而这个展开运算符可以用于部分情景:(解构赋值中展开运算符只能用在最后
let [arg1,arg2,...arg3] = [1,2,3,4];
console.log(arg1);//1
console.log(arg2);//2
console.log(arg3);//3,4
  • 注意 : 解构赋值中展开运算符只能用在最后:
let [arg1,...arg2,arg3] = [1, 2, 3, 4]; //报错

类数组对象变成数组 ?

  • 展开运算符可以将一个 类数组对象 变成一个真正的 数组对象
let list = document.querySelectorAll('div');
let arr = [...list];

总结一些常见的应用场景 ?


  • 复制数组 :
const fruits = ['apple','orange','banana'];
const fruitsCopied = [...fruits];//['apple','orange','banana']
console.log(fruits === fruitsCopied);//false
//ES5中的方法:old way
fruits.map(fruit => fruit);

注意 :…在展开基本数据类型时,是深copy,基本数据类型位于栈区;如果使用展开运算符 展开一个对象时,那么是浅copy,对象位于堆区;如果数组中是基本数据类型深copy;如果数组中有对象,就是浅copy;展开对象 对象就一层,是深copy;展开对象 对象是多层,是浅copy;可以通过  JSON.parse(JSON.stringify(obj)) 可以实现深copy 。

  • 数组去重 :
const fruits = ['apple', 'orange', 'banana', 'banana'];
const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana']
// old way
fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);
  • 合并数组 :
const fruits = ['apple', 'orange', 'banana'];
const vegetables = ['carrot'];
const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']
// 老方法
const fruitsAndVegetables = fruits.concat(vegetables);
fruits.unshift('carrot');
  • 将参数作为数组进行传递 :

const mixer = (x, y, z) => console.log(x, y, z);
const fruits = ['apple', 'orange', 'banana'];
mixer(...fruits); // 'apple', 'orange', 'banana' 
// 老方法
mixer.apply(null, fruits);
  • 数组切片 :
const fruits = ['apple', 'orange', 'banana'];
const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']
// 老方法
const remainingFruits = fruits.slice(1);
  • 将参数转换为数组 :

const mixer = (...args) => console.log(args);
mixer('apple'); // ['apple']
  • 将 NodeList (类数组)转换为数组 :
[...document.querySelectorAll('div')];
// 老方法
Array.prototype.slice.call(document.querySelectorAll('div'));
  • 复制对象 :
const todo = { name: 'Clean the dishes' };
const todoCopied = { ...todo }; // { name: 'Clean the dishes' }
console.log(todo === todoCopied); // false
// 老方法
Object.assign({}, todo);
  • 合并对象 :
const todo = { name: 'Clean the dishes' };
const state = { completed: false };
const nextTodo = { name: 'Ironing' };
const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false }
// 老方法
Object.assign({}, todo, state, nextTodo);
  • 将字符串拆分为字符 :
const country = 'USA';
console.log([...country]); // ['U', 'S', 'A']
// 老方法
country.split('');
  • 求最大值 / 最小值 :
let numbers = [9, 4, 7, 1];
Math.max(...numbers); // 9
Math.min(...numbers); // 1

 

热门文章

暂无图片
编程学习 ·

Spring Boot整合Zookeeper实现配置中心

简介 使用背景 说到配置中心,目前市面上用的较多的配置中心都广为人知,比如百度的Disconf、Spring Cloud Config、携程的Apollo、阿里的Nacos等。由于项目组一直是使用的zookeeper作为配置中心,所以来学习使用。 实现原理在Zookeeper建立一个根节点,比如/CONFIG,代表某个配…
暂无图片
编程学习 ·

搭建一个完整的微服务系统(四):微服务的公共依赖

任何一个系统中,都有一个或多个基础项目,可生成jar包给所有服务依赖。在本示例(工程basejar)中,我给大家找了一些常用的进行说明,这些内容和业务无关,大家可以直接使用。 幂等相关这部分包括:AutoIdempotent.java、AutoIdempotentInterceptor.java、TokenService.java三个…
暂无图片
编程学习 ·

Lower Frame Rate Neural Network Acoustic Models翻译

摘要 最近,使用连续时序分类(CTC)训练的神经网络声学模型被提出,作为传统的交叉熵训练的神经网络声学模型的替代方法,其中,交叉熵方法每10ms输出一帧。与传统模型相反,CTC联合声学模型一起学习对齐,并且除了传统声学状态单元外还输出空白符号。这允许CTC模型以低帧率运…
暂无图片
编程学习 ·

自适应核回归算法讲解

该文是对07年论文“Kernel Regression for Image Processing and Reconstruction”的总结性介绍。对于初学者来说,首先要搞明白“核回归”是什么意思。所谓“回归”可以简单地理解为对样本值的拟合。在目标函数中,通常会给不同样本值误差分配不同的权重,决定权重分配的函数即…
暂无图片
中恒嘉业 ·

关于主从复制的超详细解析(全)

目录前言1. 主从复制1.1 方式2. Mysql的主从复制2.1 一主一从2.1.1 window和linux通讯2.1.2 linux和linux的通讯2.2 双主双从3. Redis的主从复制3.1 哨兵模式3.2 java代码结合前言 主要介绍mysql的主从复制以及redis的主从复制 能由浅入深的明白原理以及如何操作 再者&#xf…
暂无图片
郑州普通话 ·

PyQt 控件介绍

PyQt控件介绍一、常用组件介绍1、综合示例2、讲解二、深入研究组件1、标签1.示例代码2.讲解2、文本编辑框1.示例2.讲解本节介绍的组件在前面的讲解过程中已经使用过了,这里综合前面的布局和信号,做一个统一的示例讲解,并对其中重点组件讲解更…
暂无图片
代理记账 ·

在web应用中发送和接收Jakarta消息

Running the websimplemessage Example To Package and Deploy websimplemessage Using Maven _1、Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server). _2、In a terminal window, go to: tut-install/examples/jms/websimp…
暂无图片
cgfy ·

C++学习日记2——函数、封装、对象特性

一、函数 1.1 函数默认参数 1.1.1 简介 在C中&#xff0c;函数的形参列表中的形参是可以有默认值的 1.1.2 语法 返回值类型 函数名 (参数 默认值) {} 1.1.3 代码 #include <iostream> using namespace std;// 函数的默认参数 int func(int a, int b 20, int c 30…
暂无图片
coreui ·

视频水印怎么去除?超简单 千万不要错过

小编在知乎看到很多大佬分享的视频去水印的方法&#xff0c;但是感觉都有点太复杂了&#xff0c;今天就来分享一下小编自己私藏的几个针对于视频去水印的软件和网站~建议大家收藏哦~ 1、爱给网-视频去水印小工具&#xff08;免费 在线&#xff09; 推荐点 1、在线操作&#…
暂无图片
coreui ·

Mac 安装 tomcat10

Mac 安装 tomcat10 1、下载tomcat tomcat官网&#xff1a;https://tomcat.apache.org/ 点击我下载的tomcat10&#xff1a; 2、下载解压,给bin下的*.sh文件添加可执行权限 3、修改webapps下的ROOT中的index文件查看效果
暂无图片
未来博客 ·

视频水印怎么去除?超简单 千万不要错过

小编在知乎看到很多大佬分享的视频去水印的方法&#xff0c;但是感觉都有点太复杂了&#xff0c;今天就来分享一下小编自己私藏的几个针对于视频去水印的软件和网站~建议大家收藏哦~ 1、爱给网-视频去水印小工具&#xff08;免费 在线&#xff09; 推荐点 1、在线操作&#…
暂无图片
未来博客 ·

Mac 安装 tomcat10

Mac 安装 tomcat10 1、下载tomcat tomcat官网&#xff1a;https://tomcat.apache.org/ 点击我下载的tomcat10&#xff1a; 2、下载解压,给bin下的*.sh文件添加可执行权限 3、修改webapps下的ROOT中的index文件查看效果
暂无图片
建站日记 ·

惠州实验室建设选址、勘察事项

惠州实验室建设选址、勘察事项&#xff0c;SICOLAB技术员带您从实验室建设启动前思考问题考虑如下&#xff1a;一、不同实验室建设选址要求 1.化学实验室 &#xff08;1&#xff09;清洁安静环境 &#xff08;2&#xff09;远离住宅、生活区 &#xff08;3&#xff09;锅炉房与…
暂无图片
建站日记 ·

NLP聊天机器人原理(seq2seq模型)

一、seq2seq模型 1.概念 seq2seq是一个Encoder-Decoder结构的网络&#xff0c;它的输入是一个序列&#xff0c;输出也是一个序列。Encoder中将一个可变长度的信号序列变为固定长度的向量表达&#xff0c;Decoder将这个固定长度的向量变成可变长度的目标的信号序列。这个结构最…
暂无图片
mfbz ·

惠州实验室建设选址、勘察事项

惠州实验室建设选址、勘察事项&#xff0c;SICOLAB技术员带您从实验室建设启动前思考问题考虑如下&#xff1a;一、不同实验室建设选址要求 1.化学实验室 &#xff08;1&#xff09;清洁安静环境 &#xff08;2&#xff09;远离住宅、生活区 &#xff08;3&#xff09;锅炉房与…
暂无图片
mfbz ·

全渠道会员通-天猫会员通3: 会员运营内容准备

在天猫会员通技术对接开发过程中&#xff0c;为了通知存量会员的通知工作&#xff0c;发挥会员通的优势&#xff0c;品牌需要做好以下事宜&#xff1a; 会员体系暂停公告&#xff1a;因会员通技术升级期间&#xff0c;会员服务将被暂停&#xff0c;店铺tab中会员入口将被下线&…
暂无图片
珊珊日记 ·

C# 执行Javascript脚本

c#教程https://www.xin3721.com/eschool/CSharpxin3721/ 前一阵子使用C#编写SCXML状态机&#xff0c;需要解析EMCScript表达式&#xff0c;使用了Jint库&#xff08;https://github.com/sebastienros/jint/)&#xff0c;当时感觉与C#之间的数据转换不是很方便。这两天有时间又关…
暂无图片
珊珊日记 ·

第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛

A.大学期末现状 题目描述 作为一名大学生的你&#xff0c;现在又到了期末查成绩的时候&#xff0c;当你的成绩大于等于60时请输出“jige,haoye!”,否则输出"laoshi,caicai,laolao"。 输入描述: 一行&#xff0c;一个整数x代表你的成绩&#xff08;0<x<100&a…