JavaScript扩展运算符...的实现原理

… 作用

扩展运算符(spread)是三个点(…),用于取出参数对象中的所有可遍历属性,浅拷贝到当前对象之中。

常见用法

1.浅拷贝数组

const a1 = ['test1', 'test2'];
const a2 = [...a1];a2[0] = 'test2';
a2 // ['test2', 'test2']

2.合并数据

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

3. 解构赋值

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   // []

4.字符串/类数组转为真正的数组

因为任何定义了遍历器(Iterator)接口的对象,都可以用扩展运算符转为真正的数组。

[...'test']
// [ "t", "e", "s", "t"][...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

基本实现原理

如果不用 …,如何实现一样的功能?由上面的用法,可以知道。扩展运算符主要就是浅拷贝可遍历对象属性,那么我们可以用es5的写法实现如下:

// 简单版实现
function _spread() {for (var ar = [], i = 0; i < arguments.length; i++){ar = ar.concat(arguments[i]);}return ar;
};

用上面的例子测试一下,结果如下:

const a1 = ['test1', 'test2'];
const a2 = _spread(a1);a2[0] = 'test2';
a2 // ['test2', 'test2']

可以看出上面的例子,没有考虑到属性的可遍历性判断,那么需要进一步优化。

严谨实现

这里分几种情况来考虑就好:

  1. 判断是否为数组,数组一定可迭代,则直接复制数组后返回结果即可。
  2. 判断是否为实现了遍历器(Iterator)接口的对象,若实现了则转为数组。
  3. 如果没有实现遍历器(Iterator)接口的对象,则判断是否为普通字符串/Map/Set等。
  4. 均不满足以上条件的话,则抛错。
    所以,最后实现为:
function _toConsumableArray(arr) {return (_arrayWithoutHoles(arr) || //  判断是否为数组_iterableToArray(arr) || //  判断是否为实现了遍历器(Iterator)接口的对象_unsupportedIterableToArray(arr) || // 判断是否为普调字符串/Map/Set等_nonIterableSpread() // 则抛错);
}function _nonIterableSpread() {throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}function _unsupportedIterableToArray(o, minLen) {if (!o) return;if (typeof o === "string") return _arrayLikeToArray(o, minLen);var n = Object.prototype.toString.call(o).slice(8, -1);if (n === "Object" && o.constructor) n = o.constructor.name;if (n === "Map" || n === "Set") return Array.from(o);if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o, minLen);
}function _iterableToArray(iter) {if ((typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||iter["@@iterator"] != null)return Array.from(iter);
}function _arrayWithoutHoles(arr) {if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}function _arrayLikeToArray(arr, len) {if (len == null || len > arr.length) len = arr.length;for (var i = 0, arr2 = new Array(len); i < len; i++) {arr2[i] = arr[i];}return arr2;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/815799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【vue】Vue3开发中常用的VSCode插件

Vue - Official&#xff1a;vue的语法特性&#xff0c;如代码高亮&#xff0c;自动补全等 Vue VSCode Snippets&#xff1a;自定义一些代码片段 v3单文件组件vdata数据vmethod方法 别名路径跳转 参考 https://www.bilibili.com/video/BV1nV411Q7RX

学校4-11天梯赛选拔赛

目录 L1-5 6翻了 题目 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 思路 AC代码 L1-1 嫑废话上代码 题目 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; AC代码 L1-8 刮刮彩…

HDFS、Hive、Redis、MySQL、HBase、Kafka、Flink等常用技术架构是什么?架构核心是什么?架构工作流是什么?

这些常用的技术架构在大数据和分布式系统领域发挥着重要作用&#xff0c;每个都有其特定的用途和核心组件。 HDFS (Hadoop Distributed File System)&#xff1a; 架构核心&#xff1a;HDFS是Hadoop生态系统的一部分&#xff0c;用于存储大规模数据集&#xff0c;并提供高吞吐量…

代码随想录-二叉树

************二叉树的前序遍历&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 递归 public class LeetCode144 {class TreeNode{int val;TreeNode left;TreeNode right;public TreeNode() {}public TreeNode(int val) {this.val val;}public TreeNode(int val, Tre…

初识责任链模式--一起学习吧之数据库

一、定义 责任链模式是一种对象行为型模式&#xff0c;用于处理请求发送者和多个请求处理者之间的耦合问题。在这种模式中&#xff0c;请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时&#xff0c;请求会沿着这条链传递&#xff0c;直到有对象处…

深入了解边缘AI的发展

人工智能先进功能的融合、物联网设备的广泛采用以及边缘计算的强大性能释放了边缘AI的潜力。这种变革性的协同作用涵盖了辅助医疗诊断、自动驾驶和仓库物流自动化等应用。 边缘计算起源于1990年代的内容分发网络&#xff0c;现在被广泛使用&#xff0c;尤其是在边缘AI领域。企…

Vue入门:天不生Vue,前端万古如长夜 - Vue从入门到放弃

&#x1f44b; Vue环境搭建 首先&#xff0c;搭一个打代码的环境 1.安装node.js 在使用VS Code之前&#xff0c;需要安装Vue的开发环境。 安装Vue的最简单方法是使用npm包管理器&#xff0c;先安装Node.js和npm。 node官网 ​​ 2.配置环境变量 在nodejs安装目录下新建…

免费分享Springboot+Vue的影院管理系统源码,真酷!

今天给大家分享一套基于SpringbootVue的影院管理系统源码&#xff0c;在实际项目中可以直接复用。(免费提供&#xff0c;文末自取) 一、系统运行图 1、登陆页面 2、系统后台 3、选座功能 影院管理系统通常具有以下七个功能点&#xff1a; 1.电影管理&#xff1a; 包括电影信…

https://ac.nowcoder.com/acm/contest/79505

A-KNN算法_"华为杯"华南理工大学程序设计竞赛(同步赛) (nowcoder.com) //当时就抱着试一试的心态 果然超时&#xff1a; 1.#include<bits/stdc.h> using namespace std; #define int long long const int N2e56; const int inf0x3f3f3f3f; int a[N];int c[N]…

c++ - 动态载入DLL接口,可以给IDA静态分析增加一点麻烦

文章目录 c - 动态载入DLL接口&#xff0c;可以给IDA静态分析增加一点麻烦概述笔记测试工程test_load_dll_then_call_api.cppCMyUser32Dll.hCMyUser32Dll.cppLateLoad.hIDA静态分析引入表中没有PostMessageW字符串查找能找到PostMessageW备注看看CMyUser32Dll.h编译完的样子备注…

CSS快速入门

目录 一、CSS介绍 1、什么是CSS&#xff1f; ​编辑2、基本语法规范 3、引入方式 4、规范 二、CSS选择器 1、标签选择器 2、类&#xff08;class&#xff09;选择器 3、id选择器 4、通配符选择器 5、复合选择器 三、常用CSS 1、color 2、font-size 3、border 4…

【300套】基于Springboot+Vue的Java毕业设计项目(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f9e1;今天给大家分享300的Java毕业设计&#xff0c;基于Springbootvue框架&#xff0c;这些项目都经过精心挑选&#xff0c;涵盖了不同的实战主题和用例&#xff0c;可做毕业…

电影《你想活出怎样的人生》观后感

上周去看了宫崎骏电影《你想活出怎样的人生》&#xff0c;就像作为导演问观众的一个问题一样&#xff0c;宫崎骏老爷子&#xff0c;在电影中&#xff0c;给出了他的一些开放式答案。自己可是说是宫崎骏的粉丝&#xff0c;宫崎骏老爷子的大部分电影&#xff0c;自己基本都看过了…

2024.4.10作业

#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } //显示时间 void Widget::timerEvent(QTimerEvent *e) { QT…

clion最新安装教程

还在用Dev-C吗&#xff1f;也尝试了很多C编辑器&#xff0c;不是太老&#xff0c;就是太复杂。对于c开发者来说clion真的好用&#xff0c;CLion是一款专为开发C及C所设计的跨平台IDE。难受的是cion并不免费&#xff0c;仿佛是在证明好货不贵的道理&#xff0c;只能免费用30天。…

2024年少儿编程赛事时间表整理

01 信息学奥赛路线比赛 来源:https://www.noi.cn/ 首先,信息学奥赛是升学最有帮助的一个赛事了,从CSP-J/P开始到NOIP再到最后的NOI,对科技特长生、高考加分都有较大裨益,但相对难度也是最大的。 小学可以参加的是CSP-J比赛,但是和初中生一起考试,不占优势,胜在早入门…

4.14学习总结

java网络编程 一.网络编程的概念和原理 概念: 网络编程是指通过计算机网络进行数据传输和通信的编程技术。在网络编程中&#xff0c;可以实现不同计算机之间的数据交互和通信&#xff0c;从而实现分布式系统、客户端-服务器应用等。 Java网络编程基于TCP/IP协议栈进行通信&…

低延时+高并发+强事务丨DolphinDB 交易型内存存储引擎 IMOLTP 使用指南

1. 背景 在一些数据库应用场景中&#xff0c;例如金融行业的交易系统&#xff0c;其主要工作负载来源于对关系表的高频度、高并发的更新和查询操作。这样的应用场景要求数据的读写和计算能够具有低延迟、高并发的特征&#xff0c;同时保证极高的数据一致性&#xff0c;并提供 …

离谱!奇安信人事总监透露:Web安全不会岗位这些就别投简历了

有人的地方就有江湖&#xff0c;有互联网安全的地方&#xff0c;就必然有Web安全工程师的身影。但其实Web安全是近几年才备受关注的&#xff0c;从事这方面的专业人员并不多&#xff0c;这就导致整个市场Web安全研究员的供求严重不平衡。 这种供求不平衡直接反映在Web安全研究…

软考之零碎片段记录(十五)+复习巩固(十)

一、学习 1. 多对多关系模式 举例&#xff1a;学生和课程。顾客和商品等。 多对多关系的确立需要有中间表&#xff0c;需要使用两个外键确认表中的唯一数据。 2. 数据库范式 1nf 表中每个字段都是原子性不可查分的。在关系&#xff08;或表&#xff09;中&#xff0c;每一行…