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

 

热门文章

暂无图片
编程学习 ·

Linux下用ls和du命令查看文件以及文件夹大小

ls的用法 ls -l |grep “^-”|wc -l或find ./company -type f | wc -l 查看某文件夹下文件的个数,包括子文件夹里的。 ls -lR|grep “^-”|wc -l 查看某文件夹下文件夹的个数,包括子文件夹里的。 ls -lR|grep “^d”|wc -l 说明:ls -l 长列表输出该目录下文件信息(注意这里…
暂无图片
编程学习 ·

Python入门的学习心得

由于我是自学Python,非科班出生,所以只能分享一些关于我的学习心得,如果有不对地方欢迎指正。不过非科班出生虽然是一个痛点,但是在工作上,我其实不输给我其他同事,这点我倒是很有自信,而且我也统一一句话“目前互联网上的免费编程课程,足够让你成为一个合格的码农”。…
暂无图片
编程学习 ·

支付宝小程序转微信小程序?

问题概述 支付宝小程序做完后,开始转战微信小程序;网上搜了一下都是都是微信转支付宝,并且还有转换工具(实名羡慕。。),并没有找到支付宝转换微信小程序的前车之鉴。由于拿到的是一半的项目,因此准备将支付宝与微信的区别整理出来,然后在开发者工具或者vscode进行全局替…
暂无图片
编程学习 ·

【译】理解C++中的 nullptr

原文链接🔗 Understanding nullptr in C++译者注:nullptr 是 C++11 为了解决NULL的歧义问题而引入的新特性,表示空指针常量. 原文作者是 Utkarsh Trivedi,发布网站是GeeksforGeeks.考虑下面的C++程序,它暴露了一些NULL的问题 // C++ program to demonstrate problem with N…
暂无图片
编程学习 ·

centos 怎么安装 nginx

linux centos 7 安装 nginx 原文来自官网 : http://nginx.org/en/linux_packages.html Installation instructions Before you install nginx for the first time on a new machine, you need to set up the nginx packages repository. Afterward, you can install and updat…
暂无图片
编程学习 ·

设计模式简单介绍五(模板方法模式)

模板方法模式的意图 定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 让我上去刚读到这段话我也是看不懂的,但是在现实中我们真的很常用到模板模式,通俗一些说就是如果我们需要通用的代码…
暂无图片
编程学习 ·

JMXTrans入门教程

概述 官网 GitHub JMX JMX,即Java Management Extensions,监控Java应用程序系统运行的状态信息,通过分析JMX信息,可用于监控应用程序运行状态、优化程序、排查问题。 JMXTrans JMXTrans是一款开源的JMX指标采集工具,使用简单方便,无需编写代码,只需要配置文件就可以轻松…
暂无图片
编程学习 ·

移动机器人定位研究笔记

移动机器人定位的分类 以下内容来自于Probabilistic Robotics 局部定位和全局定位 定位问题是以最初及运行期间可供使用信息的类型为特征的。随着难度的增加,分为三种类型的定位间题。 局部定位(local localization)又被称为位置跟踪(position tracking) , 假定机器入初始位姿…
暂无图片
编程学习 ·

目标跟踪环境配置(四):OTB配置安装 (从下载到绘图)

目标跟踪基础与智能前沿 点击上方链接,微信关注回复下方安装包对应的关键词,获得对应的百度云下载链接 论文原文 1) Online Object Tracking: A Benchmark 1、下载OTB数据集 1)官网下载地址(国内网速原因很慢): 2)百度云下载地址: 自动回复关键词“OTB” 2、预先安…
暂无图片
编程学习 ·

数据结构与算法(Python版)五十四:AVL树的定义和性能

平衡二叉查找树: AVL树的定义 我们来看看能够在key插入时一直保持平衡的二叉查找树: AVL树 AVL是发明者的名字缩写: G.M. AdelsonVelskii and E.M. Landis 利用AVL树实现ADT Map, 基本上与BST的实现相同 不同之处仅在于二叉树的生成与维护过程 AVL树的实现中, 需要对每个节…
暂无图片
编程学习 ·

视频项目的“云、边、端”公式

视频项目各种各样,视频方案也是千变万化,可以有多种形式的组合来解决问题,最终选择具体哪一种方案可能会根据成本、效果、可行性等多个方面来综合,那么,有没有一套公式可以解决视频项目的需求? 可以说是有的,我总结了一套视频“云、边、端”的公式,可以在具体项目实践中…
暂无图片
编程学习 ·

java编程思想——抽象类和接口的详解(实例)

文章目录一、抽象类的概念和作用1.抽象的定义2.抽象类3.抽象方法的特点4.抽象类的特点抽象类和接口为什么不能被实例化的原因二、理解抽象类和接口java类为什么是单继承?参考资料: 一、抽象类的概念和作用 1.抽象的定义 抽象是把多个事物的共性的内容抽取出来,本质就是把我们…
暂无图片
编程学习 ·

koa2+ts中为Context扩展自定义属性

问题来源 为了简化 ctx.body 赋值操作,想要在 ctx 扩展两个自定义方法, success 及 error 使用起来如下 // 响应成功状态请求 ctx.success({username: test });// 等价于 ctx.body = {code: 1,data: {username: test} };// 响应失败状态请求 ctx.error("参数不正确&quo…
暂无图片
编程学习 ·

web前端应该怎么学?

互联网+的火爆,让互联网行业快速的扩张。越来越多的人想通过学习的途径进入这个行业,java开发、WEB前端开发、UI设计等专业受到大众追捧。小编这次主要介绍一下WEB前端开发,为想要学习web前端开发的人指点迷津,能更加有效的去学习web前端开发。 web前端开发需掌握的知识 【…
暂无图片
编程学习 ·

整合腾讯云地图的绘制和编辑几何图形

官方绘制案例:https://lbs.qq.com/webDemoCenter/glAPI/glEditor/toolDraw官方编辑案例:https://lbs.qq.com/webApi/javascriptV2/jsGuide/jsCover整合绘制和编辑代码如下:记得把代码里的key改成自己的!​ <!DOCTYPE html> <html lang="en"><head…