JS中对数组的操作哪些会改变原数组哪些不会?今天你一定要记下!

news2025/1/30 13:21:25

JavaScript 数组方法:变更原数组与不变更原数组的区别

在 JavaScript 中,数组是非常常见且重要的数据结构。作为开发者,我们常常需要使用数组方法来处理数组数据。但是,数组的不同方法会以不同的方式影响原数组,它们可以分为变更原数组的方法和不变更原数组的方法。本文将详细探讨 JavaScript 中常见的数组方法,分析它们是如何工作的,并重点讨论哪些方法会修改原数组,哪些方法不会。

一、变更原数组的方法

这些方法会直接对数组本身进行修改,改变其元素、长度或结构。

1. push()

push() 方法将一个或多个元素添加到数组的末尾,并返回数组的新长度。

  • 示例:

    let arr = [1, 2, 3];
    arr.push(4);
    console.log(arr); // [1, 2, 3, 4]
    
  • 原理

    • push() 会直接修改原数组。在其内部,它会将新的元素添加到数组的末尾,并更新数组的长度。其基本实现如下:
    Array.prototype.push = function (...args) {
      let len = this.length;
      for (let i = 0; i < args.length; i++) {
        this[len + i] = args[i];
      }
      return this.length;
    };
    

2. pop()

pop() 方法删除数组的最后一个元素,并返回被删除的元素。

  • 示例:

    let arr = [1, 2, 3];
    let removedElement = arr.pop();
    console.log(arr); // [1, 2]
    console.log(removedElement); // 3
    
  • 原理

    • pop() 会修改数组并返回最后一个元素。其实现方式:
    Array.prototype.pop = function () {
      let len = this.length;
      if (len === 0) return undefined;
      let removedElement = this[len - 1];
      this.length = len - 1;
      return removedElement;
    };
    

3. shift()

shift() 方法从数组的开头删除一个元素,并返回该元素。

  • 示例:

    let arr = [1, 2, 3];
    let removedElement = arr.shift();
    console.log(arr); // [2, 3]
    console.log(removedElement); // 1
    
  • 原理

    • shift() 删除数组的第一个元素,并且其他元素会向左移动。其实现方式:
    Array.prototype.shift = function () {
      let len = this.length;
      if (len === 0) return undefined;
      let removedElement = this[0];
      for (let i = 0; i < len - 1; i++) {
        this[i] = this[i + 1];
      }
      this.length = len - 1;
      return removedElement;
    };
    

4. unshift()

unshift() 方法将一个或多个元素添加到数组的开头,并返回新数组的长度。

  • 示例:

    let arr = [1, 2, 3];
    arr.unshift(0);
    console.log(arr); // [0, 1, 2, 3]
    
  • 原理

    • unshift() 会将元素插入到数组的开头,并移动现有元素的位置。其实现代码:
    Array.prototype.unshift = function (...args) {
      let len = this.length;
      for (let i = len - 1; i >= 0; i--) {
        this[i + args.length] = this[i];
      }
      for (let i = 0; i < args.length; i++) {
        this[i] = args[i];
      }
      return this.length;
    };
    

5. reverse()

reverse() 方法将数组中的元素顺序颠倒,并直接修改原数组。

  • 示例:

    let arr = [1, 2, 3];
    arr.reverse();
    console.log(arr); // [3, 2, 1]
    
  • 原理

    • reverse() 直接改变原数组,颠倒数组元素顺序。其内部实现代码:
    Array.prototype.reverse = function () {
      let len = this.length;
      for (let i = 0; i < Math.floor(len / 2); i++) {
        let temp = this[i];
        this[i] = this[len - 1 - i];
        this[len - 1 - i] = temp;
      }
      return this;
    };
    

6. sort()

sort() 方法对数组中的元素进行排序,并返回排序后的数组。此方法会修改原数组。

  • 示例:

    let arr = [23, 12, 8, 13, 21, 9];
    arr.sort();
    console.log(arr); // [12, 13, 21, 23, 8, 9] (默认按字符串排序)
    
  • 原理

    • sort() 默认按照字符串排序,如果需要按数值排序,可以提供一个比较函数。其基本实现代码如下:
    Array.prototype.sort = function (compareFunction) {
      let len = this.length;
      for (let i = 0; i < len - 1; i++) {
        for (let j = 0; j < len - 1 - i; j++) {
          if (compareFunction(this[j], this[j + 1]) > 0) {
            let temp = this[j];
            this[j] = this[j + 1];
            this[j + 1] = temp;
          }
        }
      }
      return this;
    };
    

7. splice()

splice() 方法可以从数组中添加或删除元素,并直接修改原数组。

  • 示例:

    let arr = [1, 2, 3, 4, 5];
    arr.splice(2, 1); // 删除索引2的元素
    console.log(arr); // [1, 2, 4, 5]
    
  • 原理

    • splice() 通过删除和插入来修改原数组。其实现代码:
    Array.prototype.splice = function (start, deleteCount, ...items) {
      let removedItems = [];
      for (let i = start; i < start + deleteCount; i++) {
        removedItems.push(this[i]);
      }
      let len = this.length;
      for (let i = len - 1; i >= start + deleteCount; i--) {
        this[i + items.length] = this[i];
      }
      for (let i = 0; i < items.length; i++) {
        this[start + i] = items[i];
      }
      this.length -= deleteCount;
      return removedItems;
    };
    

二、不改变原数组的方法

这些方法会返回一个新数组,而不会修改原数组的内容。了解这些方法的实现原理,有助于我们更好地理解它们是如何工作的。

1. concat()

concat() 方法用于合并多个数组或值,并返回一个新的数组。

  • 示例:

    let arr1 = [1, 2, 3];
    let arr2 = [4, 5, 6];
    let newArr = arr1.concat(arr2);
    console.log(newArr); // [1, 2, 3, 4, 5, 6]
    console.log(arr1); // [1, 2, 3]
    console.log(arr2); // [4, 5, 6]
    
  • 原理

    • concat() 会返回一个新的数组,原数组不会改变。实现代码:
    Array.prototype.concat = function (...args) {
      let result = [...this];
      for (let i = 0; i < args.length; i++) {
        let currentArray = args[i];
        result.push(...currentArray);
      }
      return result;
    };
    

2. slice()

slice() 方法返回数组的一个浅拷贝,并不改变原数组。

  • 示例:

    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.slice(1, 4);
    console.log(newArr); // [2, 3, 4]
    console.log(arr); // [1, 2, 3, 4, 5]
    
  • 原理

    • slice() 会返回数组的一部分副本,不会改变原数组。其实现方式如下:
    Array.prototype.slice = function (start, end) {
      let result = [];
      for (let i = start || 0; i < (end || this.length); i++) {
        result.push(this[i]);
      }
      return result;
    };
    

3. map()

map() 方法通过提供的函数对数组中的每个元素进行处理,返回一个新数组,不会修改原数组。

  • 示例:

    let arr = [1, 2, 3];
    let newArr = arr.map(item => item * 2);
    console.log(newArr); // [2, 4, 6]
    console.log(arr); // [1, 2, 3]
    
  • 原理

    • map() 方法会根据提供的回调函数生成一个新数组,原数组不受影响。其实现代码:
    Array.prototype.map = function (callback) {
      let result = [];
      for (let i = 0; i < this.length; i++) {
        result.push(callback(this[i], i, this));
      }
      return result;
    };
    

4. filter()

filter() 方法基于条件返回数组中符合条件的元素组成的新数组,原数组不改变。

  • 示例:

    let arr = [1, 2, 3, 4, 5];
    let newArr = arr.filter(item => item > 3);
    console.log(newArr); // [4, 5]
    console.log(arr); // [1, 2, 3, 4, 5]
    
  • 原理

    • filter() 会根据回调函数判断每个元素是否满足条件,返回一个新数组,原数组不变。其实现代码:
    Array.prototype.filter = function (callback) {
      let result = [];
      for (let i = 0; i < this.length; i++) {
        if (callback(this[i], i, this)) {
          result.push(this[i]);
        }
      }
      return result;
    };
    

5. join()

join() 方法将数组的所有元素连接成一个字符串,并返回该字符串。

  • 示例:

    let arr = [1, 2, 3];
    let result = arr.join("-");
    console.log(result); // "1-2-3"
    console.log(arr); // [1, 2, 3]
    
  • 原理

    • join() 返回一个由数组元素连接而成的字符串,原数组没有改变。其实现方式如下:
    Array.prototype.join = function (separator = ',') {
      let result = '';
      for (let i = 0; i < this.length; i++) {
        if (i > 0) result += separator;
        result += this[i];
      }
      return result;
    };
    

6. some()

some() 方法检查数组中是否有至少一个元素符合条件,返回布尔值,原数组不变。

  • 示例:

    let arr = [1, 2, 3, 4];
    let result = arr.some(item => item > 3);
    console.log(result); // true
    console.log(arr); // [1, 2, 3, 4]
    
  • 原理

    • some() 检查数组中是否有符合条件的元素,如果有则返回 true,否则返回 false。原数组不受影响,代码实现如下:
    Array.prototype.some = function (callback) {
      for (let i = 0; i < this.length; i++) {
        if (callback(this[i], i, this)) {
          return true;
        }
      }
      return false;
    };
    

7. every()

every() 方法检查数组中的每个元素是否都满足条件,返回布尔值,原数组不变。

  • 示例:

    let arr = [1, 2, 3, 4];
    let result = arr.every(item => item > 0);
    console.log(result); // true
    console.log(arr); // [1, 2, 3, 4]
    
  • 原理

    • every() 会判断数组中的所有元素是否都满足给定条件,如果都满足返回 true,否则返回 false。其实现代码如下:
    Array.prototype.every = function (callback) {
      for (let i = 0; i < this.length; i++) {
        if (!callback(this[i], i, this)) {
          return false;
        }
      }
      return true;
    };
    

至此,我们已经完成了 数组操作以及操作是否改变数组本身的源码分析 的完整解析。通过源码实现的方式,我们了解了不同数组方法是如何工作的,哪些方法会修改原数组,哪些方法不会。掌握这些方法的内部原理可以帮助我们在开发中更好地选择使用合适的数组操作方法。

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

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

相关文章

公式与函数的应用

一 相邻表格相乘 1 也可以复制 打印标题

ShenNiusModularity项目源码学习(7:数据库结构)

ShenNiusModularity项目默认使用mysql数据库&#xff0c;数据库连接字符串放到了ShenNius.Admin. Mvc、ShenNius.Admin.Hosting的appsettings.json文件内。   ShenNiusModularity项目为自媒体内容管理系统&#xff0c;支持常规管理、CMS管理、商城管理等功能&#xff0c;其数…

手撕Diffusion系列 - 第九期 - 改进为Stable Diffusion(原理介绍)

手撕Diffusion系列 - 第九期 - 改进为Stable Diffusion&#xff08;原理介绍&#xff09; 目录 手撕Diffusion系列 - 第九期 - 改进为Stable Diffusion&#xff08;原理介绍&#xff09;DDPM 原理图Stable Diffusion 原理Stable Diffusion的原理解释Stable Diffusion 和 Diffus…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(三)

Understanding Diffusion Models: A Unified Perspective&#xff08;三&#xff09; 文章概括 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A unified perspective},author{Luo, Calvin},journal{arXiv preprint arXiv:…

修改maven的编码格式为utf-8

1.maven默认编码为GBK 注:配好MAVEN_HOME的环境变量后,在运行cmd. 打开cmd 运行mvn -v命令即可. 2.修改UTF-8为默认编码. 设置环境变量 变量名 MAVEN_OPTS 变量值 -Xms256m -Xmx512m -Dfile.encodingUTF-8 3.保存,退出cmd.重新打开cmd 运行mvn -v命令即可. 源码获取&…

从AD的原理图自动提取引脚网络的小工具

这里跟大家分享一个我自己写的小软件&#xff0c;实现从AD的原理图里自动找出网络名称和引脚的对应。存成文本方便后续做表格或是使用简单行列编辑生成引脚约束文件&#xff08;如.XDC .UCF .TCL等&#xff09;。 我们在FPGA设计中需要引脚锁定文件&#xff0c;就是指示TOP层…

【数据结构】(1)集合类的认识

一、什么是数据结构 1、数据结构的定义 数据结构就是存储、组织数据的方式&#xff0c;即相互之间存在一种或多种关系的数据元素的集合。 2、学习数据结构的目的 在实际开发中&#xff0c;我们需要使用大量的数据。为了高效地管理这些数据&#xff0c;实现增删改查等操作&…

解决使用Selenium时ChromeDriver版本不匹配问题

在学习Python爬虫过程中如果使用Selenium的时候遇到报错如下session not created: This version of ChromeDriver only supports Chrome version 99… 这说明当前你的chrome驱动版本和浏览器版本不匹配。 例如 SessionNotCreatedException: Message: session not created: This…

CAN波特率匹配

STM32 LinuxIMX6ull&#xff08;Linux&#xff09;基于can-utils测试

JavaScript中的相等运算符:`==`与`===`

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战

服务容器化构建的环境配置构建前需要解决什么下面我们带着问题分析构建的过程:1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?2. 构建之前动态修改项目的环境变量3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服…

66-《虞美人》

虞美人 虞美人&#xff08;学名&#xff1a;Papaver rhoeas L.&#xff09;&#xff1a;一年生草本植物&#xff0c;全体被伸展的刚毛&#xff0c;稀无毛。茎直立&#xff0c;高25-90厘米&#xff0c;具分枝。叶片轮廓披针形或狭卵形&#xff0c;羽状分裂&#xff0c;裂片披针形…

obsidian插件——Metadata Hider

原本是要找导出图片时显示属性的插件&#xff0c;奈何还没找到&#xff0c;反而找到了可以隐藏属性的插件。唉&#xff0c;人生不如意&#xff0c;十之八九。 说一下功能&#xff1a; 这个插件可以把obsidian的文档属性放在右侧显示&#xff0c;或者决定只显示具体几项属性&a…

特种作业操作之低压电工考试真题

1.下面&#xff08; &#xff09;属于顺磁性材料。 A. 铜 B. 水 C. 空气 答案&#xff1a;C 2.事故照明一般采用&#xff08; &#xff09;。 A. 日光灯 B. 白炽灯 C. 压汞灯 答案&#xff1a;B 3.人体同时接触带电设备或线路中的两相导体时&#xff0c;电流从一相通过人体流…

[免费]基于Python的Django博客系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的基于Python的Django博客系统&#xff0c;分享下哈。 项目视频演示 【免费】基于Python的Django博客系统 Python毕业设计_哔哩哔哩_bilibili 项目介绍 随着互联网技术的飞速发展&#xff0c;信息的传播与…

进程池的制作(linux进程间通信,匿名管道... ...)

目录 一、进程间通信的理解 1.为什么进程间要通信 2.如何进行通信 二、匿名管道 1.管道的理解 2.匿名管道的使用 3.管道的五种特性 4.管道的四种通信情况 5.管道缓冲区容量 三、进程池 1.进程池的理解 2.进程池的制作 四、源码 1.ProcessPool.hpp 2.Task.hpp 3…

Gurobi 基础语法之 tupledict 和 tuplelist

Python中的字典&#xff1a;dict 我们先来介绍一下Python语法中的 dict 类型, 字典中可以通过任意键值来对数据进行映射&#xff0c;任何无法修改的python对象都可以当作键值来使用&#xff0c;这些无法修改的Python对象包括&#xff1a;整数(比如&#xff1a;1)&#xff0c;浮…

Flutter:搜索页,搜索bar封装

view 使用内置的Chip简化布局 import package:chenyanzhenxuan/common/index.dart; import package:ducafe_ui_core/ducafe_ui_core.dart; import package:flutter/material.dart; import package:get/get.dart; import package:tdesign_flutter/tdesign_flutter.dart;import i…

IoTDB 2025 春节值班与祝福

2025 春节快乐 瑞蛇迎吉庆&#xff0c;祥光映华年&#xff0c;2025 春节已近在眼前。社区祝福 IoTDB 的所有关注者、支持者、使用者 2025 新年快乐&#xff0c;“蛇”来运转&#xff01; IoTDB 团队的春节放假时间为 2025 年 1 月 27 日至 2 月 4 日&#xff0c;1 月 25 日、26…

刀客doc:禁令影响下,TikTok广告业务正在被对手截胡

一、 现如今&#xff0c;TikTok在美国的命运迎来了暂时的反转&#xff0c;根据Adage的报道&#xff0c;广告主的投放在恢复。但短暂的关闭带来的影响依然有余震&#xff0c;一些广告主在重新评估TikTok在自己广告预算中的地位&#xff0c;这些是竞争对手截胡的机会。 长期以…