当前位置: 首页 > news >正文

ES6扩展运算符——三个点(...)用法详解

目录

1  含义

2  替代数组的 apply 方法

3  扩展运算符的应用

( 1 )合并数组

( 2 )与解构赋值结合

( 3 )函数的返回值

( 4 )字符串

( 5 )实现了 Iterator 接口的对象

( 6 ) Map 和 Set 结构, Generator 函数


1  含义

扩展运算符( spread )是三个点(...)。又叫展开运算符,它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。 ——参考:【JS高级】ES6_剩余参数、打散数组-CSDN博客

展开语法 (Spread syntax), 可以在函数调用/数组构造时,将数组表达式或者 string 在语法层面展开;还可以在构造字面量对象时,将对象表达式按 key-value 的方式展开。(译者注: 字面量一般指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造方式)


参考:展开语法 - JavaScript | MDN 

console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

该运算符主要用于函数调用。

var array=[1,2,3,4,5]
var items=[6,7]
function push(array, ...items) {
array.push(...items);
}
push(array,...items) // 9 返回数组的长度function add(x, y) {
return x + y;
}
var numbers = [4, 38];
add(...numbers) // 42

上面代码中,array.push(...items)和add(...numbers)这两行,都是函数的调用,它们的都使用了扩展运算符。该运算符将一个数组,变为参数序列。

扩展运算符与正常的函数参数可以结合使用,非常灵活。

function f(v, w, x, y, z) {return v + w + x + y + z}
var args = [0, 1];
f(-1, ...args, 2, ...[3]); // 5

2  替代数组的 apply 方法

由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

// ES5 的写法
function f(x, y, z) {return x + y + z
}
var args = [0, 1, 2];
f.apply(null, args); // 3// ES6 的写法
function f(x, y, z) {return x + y + z
}
var args = [0, 1, 2];
f(...args); // 3

下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。

// ES5 的写法
Math.max.apply(null, [14, 3, 77]); // 77// ES6 的写法
Math.max(...[14, 3, 77]); // 77//  等同于
Math.max(14, 3, 77); // 77// Math.max()以及Math.min(),不能直接传入一个数组,因为它们不支持获得数组中的最大值或最小值

上面代码表示,由于 JavaScript 不提供求数组最大元素的函数,所以只能套用Math.max函数,将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用Math.max了。

另一个例子是通过push函数,将一个数组添加到另一个数组的尾部。

// ES5 的写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2); // 6 数组的push方法,返回数组的长度// ES6 的写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2); // 6 数组的push方法,返回数组的长度

上面代码的 ES5 写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。

下面是另外一个例子。

// ES5
new (Date.bind.apply(Date, [null, 2024, 2, 2]))// ES6
new Date(...[2024, 2, 2]);

3  扩展运算符的应用

( 1 )合并数组

扩展运算符提供了数组合并的新写法。

// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

( 2 )与解构赋值结合

扩展运算符可以与解构赋值结合起来,用于生成数组。

// ES5
a = list[0], rest = list.slice(1) // slice 数组的截取方法
// ES6
[a, ...rest] = list// 下面是另外一些例子。
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]const [first, ...rest] = [];
first // undefined
rest // []:const [first, ...rest] = ["foo"];
first // "foo"
rest // []

如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

const [...butLast, last] = [1, 2, 3, 4, 5];
//  报错:Uncaught SyntaxError: Rest element must be last element
const [first, ...middle, last] = [1, 2, 3, 4, 5];
//  报错:Uncaught SyntaxError: Rest element must be last element

( 3 )函数的返回值

JavaScript 的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。

var dateFields = readDateFields(database);
var d = new Date(...dateFields);

上面代码从数据库取出一行数据,通过扩展运算符,直接将其传入构造函数Date。

( 4 )字符串

扩展运算符还可以将字符串转为真正的数组。

[...'hello'] // [ "h", "e", "l", "l", "o" ]

上面的写法,有一个重要的好处,那就是能够正确识别 32 位的 Unicode 字符。

'x\uD83D\uDE80y'.length // 4
[...'x\uD83D\uDE80y'].length // 3

上面代码的第一种写法, JavaScript 会将 32 位 Unicode 字符,识别为 2 个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。

function length(str) {
return [...str].length;
}
length('x\uD83D\uDE80y') // 3

凡是涉及到操作 32 位 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。

let str = 'x\uD83D\uDE80y';
str.split('').reverse().join('')
// 'y\uDE80\uD83Dx'
[...str].reverse().join('')
// 'y\uD83D\uDE80x'

上面代码中,如果不用扩展运算符,字符串的reverse操作就不正确。

( 5 )实现了 Iterator 接口的对象

任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组。

var nodeList = document.querySelectorAll('div');
var array = [...nodeList];

上面代码中,querySelectorAll方法返回的是一个nodeList对象。它不是数组,而是一个类似数组的对象,即类数组对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了 Iterator 接口。

对于那些没有部署 Iterator 接口的类似数组的对象,扩展运算符就无法将其转为真正的数组。

let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// TypeError: Cannot spread non-iterable object.
let arr = [...arrayLike]; // TypeError: arrayLike is not iterable// 使用Array.from方法将arrayLike转为真正的数组,方可使用扩展运算符
let Arr =Array.from(arrayLike);
let newArr =[...Arr];
console.log(newArr); // ['a', 'b', 'c']

上面代码中,arrayLike是一个类似数组的对象,但是没有部署 Iterator 接口,扩展运算符就会报错。这时,可以改为使用Array.from方法将arrayLike转为真正的数组。

( 6 ) Map 和 Set 结构, Generator 函数

扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构

let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]

Generator 函数运行后,返回一个遍历器对象,因此,也可以使用扩展运算符。

参考:ES6 新增函数类型——Generator 函数使用方法详解

var go = function*(){
yield 1;
yield 2;
yield 3;
};
[...go()] // [1, 2, 3]

上面代码中,变量go是一个 Generator 函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值,转为一个数组。

如果对没有iterator接口的对象,使用扩展运算符,将会报错。

var obj = {a: 1, b: 2};
// TypeError: obj is not iterable
let arr = [...obj]; // TypeError: Cannot spread non-iterable object

参考资料

展开语法 - JavaScript | MDN | 剩余参数 - JavaScript | MDN

JavaScript展开运算符和剩余运算符的区别详解_javascript技巧_脚本之家

ES6 展开语法(...)与剩余参数-CSDN博客 | JavaScript中剩余参数的使用详解_脚本之家

相关文章:

ES6扩展运算符——三个点(...)用法详解

目录 1 含义 2 替代数组的 apply 方法 3 扩展运算符的应用 &#xff08; 1 &#xff09;合并数组 &#xff08; 2 &#xff09;与解构赋值结合 &#xff08; 3 &#xff09;函数的返回值 &#xff08; 4 &#xff09;字符串 &#xff08; 5 &#xff09;实现了 Iter…...

限制资源使用

限制资源使用 您需要显示对服务器资源的访问来保护Web应用程序和应用程序数据不受未授权用户的访问。在Java EE Web应用程序中,您可以通过在应用服务器中创建用户和用户组来保护资源免受未经授权的访问。您可以为应用程序定义角色并在部署过程中将角色分配给用户。 1. 创建授权…...

结合Next项目实际认识webpack.splitChunks

本文的目的在于简单的介绍webpack的优化功能配置&#xff1a;splitChunks。 webpack5出于“开箱即用”的目的&#xff0c;将大部分曾经要使用插件的功能集成到了config配置中&#xff0c;因此用户只需要了解如何配置&#xff0c;即可达到优化目的&#xff0c;其中最常使用接触的…...

【Tauri】(2):使用Tauri应用开发,使用开源的Chatgpt-web应用做前端,使用rust 的candle做后端,本地运行小模型桌面应用

视频演示地址 https://www.bilibili.com/video/BV17j421X7Zc/ 【Tauri】&#xff08;2&#xff09;&#xff1a;使用Tauri应用开发&#xff0c;使用开源的Chatgpt-web应用做前端&#xff0c;使用rust 的candle做后端&#xff0c;本地运行小模型桌面应用 1&#xff0c;做一个免…...

C#where T :通用的泛型约束(generic constraint)语法

在C#中&#xff0c;where T :是一种通用的泛型约束&#xff08;generic constraint&#xff09;语法&#xff0c;用于限制泛型类型参数T的特定条件。通过使用泛型约束&#xff0c;我们可以对泛型类型参数进行更具体的限制&#xff0c;以确保在使用泛型时满足特定的要求。 wher…...

vue使用Mars3d弹框嵌套video视频/实时视频(m3u8)使用hls.js

下载hls.js http://mars3d.cn/lib/video/hls/hls.js下载 1.首先绘制地图我使用的天地图 async infoMars3d() {const that this;var mapOptions {scene: {center: {lat: 30.435192,lng: 103.936535,alt: 200000,heading: 359,pitch: -79},highDynamicRange: false},// 方式1&a…...

Python爬虫之Ajax数据爬取基本原理

前言 有时候我们在用 requests 抓取页面的时候&#xff0c;得到的结果可能和在浏览器中看到的不一样&#xff1a;在浏览器中可以看到正常显示的页面数据&#xff0c;但是使用 requests 得到的结果并没有。这是因为 requests 获取的都是原始的 HTML 文档&#xff0c;而浏览器中…...

osg操控器和键盘切换操控器学习

osg提供了很多操控器,在src\osgGA目录下,cpp文件名含有Manipulator的都是操控器,每个这样的cpp表示一种类型的操控器。 名字带 Manipulator 的类都是操控器; 其中KeySwitchMatrixManipulator.cpp文件实现了键盘切换操控器; 操控器是指:操控相机运动,从而实现场景视图…...

LeetCode1143. Longest Common Subsequence——动态规划

文章目录 一、题目二、题解 一、题目 Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0. A subsequence of a string is a new string generated from the original string with so…...

利用Windows10漏洞破解密码(保姆级教学)

前言: 本篇博客只是技术分享并非非法传播知识,实验内容均是在虚拟机中进行,并非真实环境 正文: 一.windows10电脑密码破解 1)开启windows10虚拟机,停留在这个页面 2&#xff09;按5次Shift键,出现这个粘滞键,如果没有出现的,则说明漏洞已经修复 3)重新启动,在这个页面的时候…...

apk反编译修改教程系列---简单修改apk默认横竖屏显示 手机端与电脑端同步演示【十一】

往期教程&#xff1a; apk反编译修改教程系列-----修改apk应用名称 任意修改名称 签名【一】 apk反编译修改教程系列-----任意修改apk版本号 版本名 防止自动更新【二】 apk反编译修改教程系列-----修改apk中的图片 任意更换apk桌面图片【三】 apk反编译修改教程系列---简单…...

2301: 不定方程解的个数

题目描述 输出不定方程解的个数。在数学中&#xff0c;不定方程是数论中的一个重要课题&#xff0c;在各种比赛中也常常出现. 对于不定方程&#xff0c;有时我们往往只求非负整数解&#xff0c;现有方程axbyc0&#xff0c;其中x、y为未知量且不超过10000&#xff0c;当给定a、…...

vue3学习——封装菜单栏

/Layout/Sidebar/index.vue <script setup lang"ts"> import Sidebar from ./Sidebar.vue // 在下面的代码里 import { useRoute } from vue-router import useUserStore from /store/modules/user.ts // state中存放菜单数据 import useLayoutSetting from /…...

深度学习的进展及其在各领域的应用

深度学习&#xff0c;作为人工智能的核心分支&#xff0c;近年来在全球范围内引起了广泛的关注和研究。它通过模拟人脑的学习机制&#xff0c;构建复杂的神经网络结构&#xff0c;从大量数据中学习并提取有用的特征表示&#xff0c;进而解决各种复杂的模式识别问题。 一、深度…...

blender怎么保存窗口布局,怎么设置默认输出文件夹

进行窗口布局大家都会&#xff0c;按照自己喜好来就行了&#xff0c;设置输出文件夹如图 这些其实都简单。关键问题在于&#xff0c;自己调好了窗口布局&#xff0c;或者设置好了输出文件夹之后&#xff0c;怎么能让blender下次启动的时候呈现出自己设置好的窗口布局&#xff…...

【开源】基于JAVA+Vue+SpringBoot的实验室耗材管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 耗材档案模块2.2 耗材入库模块2.3 耗材出库模块2.4 耗材申请模块2.5 耗材审核模块 三、系统展示四、核心代码4.1 查询耗材品类4.2 查询资产出库清单4.3 资产出库4.4 查询入库单4.5 资产入库 五、免责说明 一、摘要 1.1…...

【ES】--Elasticsearch的分词器详解

目录 一、前言二、分词器原理1、常用分词器2、ik分词器模式3、指定索引的某个字段进行分词测试3.1、采用ts_match_analyzer进行分词3.2、采用standard_analyzer进行分词三、如何调整分词器1、已存在的索引调整分词器2、特别的词语不能被拆开一、前言 最近项目需求,针对客户提…...

【算法】{画决策树 + dfs + 递归 + 回溯 + 剪枝} 解决排列、子集问题(C++)

文章目录 1. 前言2. 算法例题 理解思路、代码46.全排列78.子集 3. 算法题练习1863.找出所有子集的异或总和再求和47.全排列II17.电话号码的字母组合 1. 前言 dfs问题 我们已经学过&#xff0c;对于排列、子集类的问题&#xff0c;一般可以想到暴力枚举&#xff0c;但此类问题用…...

sqlserver 存储过程

在 SQL Server 中&#xff0c;存储过程&#xff08;Stored Procedure&#xff09;是一种预编译的 SQL 代码块&#xff0c;可以接受参数&#xff0c;执行一系列 SQL 语句&#xff0c;并返回一个或多个结果集。存储过程可以看作是一种封装了 SQL 语句的函数&#xff0c;可以在需要…...

C语言什么是悬空指针?

一、问题 什么是悬空指针&#xff1f;为什么会出现&#xff1f;我们该如何避免悬空指针的出现&#xff1f; 二、解答 在C语言中&#xff0c;悬空指针指的是指向已删除&#xff08;或释放&#xff09;的内存位置的指针。如果一个指针指向的内存被释放&#xff0c;但指针本身并未…...

RTX4090D显存优化:OpenClaw长文本处理实测Qwen3-32B性能

RTX4090D显存优化&#xff1a;OpenClaw长文本处理实测Qwen3-32B性能 1. 测试背景与实验设计 去年我在处理学术论文时&#xff0c;经常遇到需要分析几十页PDF的情况。传统工具要么截断文本&#xff0c;要么丢失关键上下文。当我发现OpenClaw支持本地部署大模型后&#xff0c;立…...

AOP 代理对象的诞生时刻:Bean 生命周期中的“夺舍”瞬间

各位大佬&#xff0c;欢迎来到 Spring 容器最神秘、最惊心动魄的现场&#xff01;很多人以为 AOP 是“天生”的&#xff0c; Bean 一出生就带着光环。大错特错&#xff01;不过是前人在负重前行&#xff1a;Spring 先造出一个“纯净的肉身”&#xff08;原始对象&#xff09;&a…...

《计算机网络》再学习

1.TCP/IP与OSI模型1&#xff09;TCP/IP模型应用层&#xff1a;为程序提供网络服务。协议&#xff1a;HTTP&#xff0c;DNS与FTP等传输层&#xff1a;提供端到端的通信服务&#xff0c;确保数据的可靠传输。协议&#xff1a;TCP与UDP网络层&#xff1a;负责数据包的路由与转发。…...

基于西门子PLC的矿井通风控制系统(含IO表、PLC引脚图、程序) PLC程序设计,价格便宜

基于西门子PLC的矿井通风控制系统&#xff08;含IO表、PLC引脚图、程序&#xff09; PLC程序设计&#xff0c;价格便宜&#xff0c;plc触摸屏上位机程序设计&#xff0c;编写。 西门子plc仿真程序设计 提供程序说明&#xff0c; plc程序代写 PLC程序设计、代做 图片为案例 接设…...

OpenClaw多设备同步:GLM-4.7-Flash配置共享方案

OpenClaw多设备同步&#xff1a;GLM-4.7-Flash配置共享方案 1. 为什么需要多设备同步配置&#xff1f; 去年冬天&#xff0c;我在办公室和家里两台MacBook上分别部署了OpenClaw对接GLM-4.7-Flash模型。很快发现一个头疼的问题&#xff1a;每次在办公室调试好的技能参数&#…...

2026年必看:专业婚恋软件推荐,找到真爱不迷路

在当今快节奏的社会中&#xff0c;越来越多的高知青年面临着交友难、脱单难的问题。传统的社交方式往往难以满足他们对高质量伴侣的需求&#xff0c;而专业的婚恋软件则成为他们寻找真爱的重要途径。本文将重点推荐一款备受好评的婚恋软件——即恋App&#xff0c;并结合具体数据…...

语音播报实时

目录 GPT-SoVITS&#xff08;强烈推荐&#xff09; Fish Speech-1.5 GPT-SoVITS&#xff08;强烈推荐&#xff09; RVC-Boss/GPT-SoVITS: 1 min voice data can also be used to train a good TTS model! (few shot voice cloning) Fish Speech-1.5 追求极致流畅的实时对话&a…...

Flink技术实践-超时异常踩坑与优化

一、背景介绍在Flink实时计算的生产环境中&#xff0c;最令人头疼的往往不是复杂的业务逻辑&#xff0c;而是那些突如其来的“超时异常”。这些异常就像是系统中的“幽灵”&#xff0c;通常在业务高峰期或网络抖动时出现&#xff0c;导致作业重启、数据延迟甚至数据丢失。最近几…...

从RS485到TCP/IP:Modbus协议V1.1b3的三种组网方式对比(含WireShark抓包分析)

从RS485到TCP/IP&#xff1a;Modbus协议V1.1b3的三种组网方式深度实战解析 在工业自动化领域&#xff0c;Modbus协议已经服役超过40年&#xff0c;却依然保持着惊人的生命力。作为工程师&#xff0c;我们常常面临一个关键抉择&#xff1a;在RS485、Modbus和TCP/IP这三种主流组…...

别再瞎装了!用NVIDIA-SMI一键查CUDA版本,保姆级PyTorch 2.6.0安装避坑指南

深度学习环境搭建实战&#xff1a;从CUDA版本诊断到PyTorch 2.6.0完美安装 刚接触深度学习的新手最常遇到的"入门杀"问题&#xff0c;往往不是模型调参或代码编写&#xff0c;而是环境搭建这个看似简单的环节。我见过太多人在安装PyTorch时直接复制粘贴网上的pip命令…...