一个前端开发者的救赎之路-JS基础回顾(五)-数组

一: 创建数组

1. 数组字面量

js 复制代码
let a = []
var b = [1, 'a', true]

注意: 还有一个稀疏数组,反正我没用过,工作中也很少见人用,大多数规范都不让用稀疏数组

2. 对可迭代对象使用...扩展操作符(ES6)

2.1 可迭代对象

  • 可迭代对象是指可以用for/of循环遍历的对象,如数组、字符串,集合和映射等

2.2 ...扩展操作符

  • ES2018以后,...扩展操作符在对象字面量也可以使用了
  • 出现在等号右边或参数位置的 ... 通常是展开(拆开)。
  • 出现在等号左边或参数声明的 ... 通常是剩余(收集)。

2.3 扩展操作符是创建数组(浅)副本的一种便携方式:(浅拷贝)

js 复制代码
let originalArr = [1,2,3];
let copyArr = [...origonalArr];
copyArr[0] = 0;    // 修改copyArr不会影响originalArr
originalArr[0]      // => 1


const original = { hobbies: ['reading', 'swimming'] };
const copy = { ...original }; // 浅拷贝

// 修改嵌套数组中的元素(修改第二层)
copy.hobbies[0] = 'gaming';

console.log(original.hobbies); // 输出: ['gaming', 'swimming'] (被影响了!)
console.log(copy.hobbies);     // 输出: ['gaming', 'swimming']

3. Array()构造函数

3.1 不传参调用

  • let a = new Array(); 这样会创建一个没有元素的空数组,等价于字面量[]

3.2 传入一个数组参数,指定长度:

  • let a = new Array(10);
  • 这样会创建一个指定长度的数组。
  • 如果提前知道需要多少个数组元素,可以这样做来预先为数组分配空间
  • 注意:这时的数组中不会存储任何值,数组索引属性"0", "1"等甚至都没有定义

3.3 传入两个或更多个数组元素,或传入一个非数值元素

  • 这样调用的话,构造函数的参数会成为新数组的元素。使用数组字面量永远比这种方法简单。
js 复制代码
// [5, 4, 3, 2, 1, 'testing, testing']
let a = new Array(5, 4, 3, 2, 1, "testing, testing")
// ['sddsdsdsd']
let b = new Array('sddsdsdsd')

3.4 工厂方法Array.of()和Array.from()

  1. Array.of()

    • 解决了Array()在使用数值参数时,如果只有一个参数,这个参数指定的是数组的长度,多个又变成了数组元素

    • Array.of(),可以使其参数值(无论多少个)多为数组的元素来创建并返回新数组

      js 复制代码
      Array.of([1,2,3]); // [[1,2,3]]
      Array.of(3);       // [3]
  2. Array.from()

    • 这个方法就是将一个类数组对象或者一个可迭代对象转换成新数组,如果传入的是可迭代对象,那他就和使用...扩展操作符操作一样
    • Array.from()定义了一种给类数组对象创建真正的数组副本的机制

二、数组的增删改查

1. 读写

  • \]操作符中间包裹一个索引

2. 数组的长度

  • 每个数组都有length属性,正是这个属性让数组有别于常规的JavaScript对象,对于非稀疏数组,length属性就是数组中元素的个数。这个值比数组的最高索引大1

3. 增删

3.1 添加

  • 使用一个新索引赋值:例如:arr[arr.length] = 0
  • push(): 等同于arr[arr.length],末尾追加
  • unshift(): 从开头追加

3.2 删除

  • 可以使用delete操作符
js 复制代码
let a = [1,2,3];
delete a[2];    // 现在索引2没有元素了
2 in a;         // => false: 数组索引2没有定义
a.length;       // => 3: 删除元素不影响数组长度
  • 把数组length设置成一个新长度值,也可以从末尾删除元素
  • splice()是一个可以插入,删除或替换数组元素的通用方法
  • pop()删除最后的元素,并返回删除值
  • shift()删除第一个元素,并返回删除值

三、数组的方法

1 迭代方法(循环)

简介

首先,所有这些方法都接收一个函数作为第一个参数,并且对数组的每一个元素(或某些元素)都调用一次这个函数。如果数组是稀疏的,则不会对不存在的元素调用传入这个函数。多数情况下,我们提供的这个函数被调用时都会接收到3个参数,分别是数组元素的值数组元素的索引数组本身通常我们只需要这几个参数中的第一个,可以忽略第二和第三个值。

多数迭代器方法都接收可选的第二个参数。如果指定这个参数,则第一个函数在被调用时就好像它是第二个参数的方法一样。换句话说,我们传入的第二个参数会成为作为第一个参数传入的函数内部的this值。传入函数的返回值通常不重要,但不同的方法会以不同的方式处理这个返回值。本节介绍的所有方法都不会修改调用它们的数组。(当然,传入的函数可能会修改这个数组)

forEach()

注意:forEach()并未提供一种提前终止迭代的方式。换句话说,在这里没有常规for循环中的break语句对等的机制。

map()

  • map()方法把调用它的数组的每个元素分别传给我们指定的函数,返回这个函数的返回值构成的数组。
  • 对于map()方法来说,我们传入的函数应该有返回值
  • 注意:map()返回一个新数组,并不修改原数组
  • 如果数组是稀疏的,则缺失的元素不会调用我们的函数,但返回的数组也会与原始数组一样稀疏:长度相同,缺失的元素也相同。

filter()

  • filter()方法返回一个数组,该数组包含调用它的数组的子数组
  • 传给这个方法的函数应该是断言函数即返回true或false的函数。这个函数与传给forEach()和map()的函数一样被调用。如果函数返回true或返回值能转换为true,则传给这个函数的的元素就是filter最终返回的子数组的成员
  • 注意:filter()会跳过稀疏数组中缺失的元素,它返回的数组始终是稠密的。因此可以使用该方法清掉稀疏数组中的空隙
  • 用自己的话来说,这就是一个过滤函数,返回一个包含满足条件元素的数组

find()与findIndex()

  • find(),在找到满足条件的第一个元素时停止迭代,返回匹配的值;找不到满足条件的元素,返回undefined。
  • findIndex(),在找到满足条件的第一个元素时停止迭代,返回匹配的值的索引;找不到满足条件的元素,返回-1。

every()与some()

  • every(),类似数学上的"全称"量词∀类似,它在且只在所有元素都满足断言函数的时候,才返回true
  • some(),类似数学上的"存在"量词∃类似,它是只要有一个元素满足断言函数的时候,就返回true,但必须所有元素都不满足的时候才返回false
  • 注意: some()遇到第一个返回true的就会停止迭代。同样,every()遇到第一个返回false的也会停止迭代。
  • 注意: 如果空数组调用它们,every()返回true,some()返回false

reduce()与reduceRight()

  • reduce()和reduceRight()方法使用我们指定的函数归并数组元素,最终产生一个值。

  • reduce()接收两个参数。第一个是执行归并的函数。第二个参数是可选的,是传给归并函数的初始值。

  • 在reduce()中使用的函数与在forEach()和map()中使用的函数不一样。我们熟悉的值、索引和数组本身在这里作为第二、第三和第四参数。第一个参数是目前为止归并操作的累积结果。

  • 如果reduce()调用时未传第二个参数,那么数组的第一个元素会被作为初始值

  • 如果不传初始值,在空数组上调用reduce()会导致TypeError。如果调用它时只有一个值,或者用空数组调用但传了初始值,则reduce直接返回这个值,不会调用归并函数

  • reduceRight()与reduce()类似,只不过从高索引向低索引(从右向左)处理数组,而不是从低向高。如果归并操作具有从右到左的结合性,那可能要考虑使用reduceRight(), 比如:

    js 复制代码
    // 计算2^(3^4)。求幂具有从右到左的优先级
    let a = [2, 3, 4]
    a.reduceRight((acc, val) => Math.pow(val, acc))
  • 注意: 无论reduce()还是reduceRight()都不接收用于指定归并函数this值的可选参数。它们用可选的初始值参数取代了这个值。如果需要可以考虑bind()方法

2. 使用flat()和flatMap()打平数组

  • flat()只能打平一级

    js 复制代码
    [1, 2, [3, 4, [5]]].flat() // =>[1, 2, 3, 4, [5]]
  • flatMap()方法与map()方法类似,只不过返回的数组会自动被打平,就像传给了flat()一样。换句话说,调用a.flatMap(f)等同于(但效率远高于)a.map(f).flat()

相关推荐
朱程4 小时前
深入JS(一):手写 Promise
前端·javascript
Hierifer4 小时前
跨端技术:浅聊双线程原理和实现
前端
FreeBuf_4 小时前
加密货币武器化:恶意npm包利用以太坊智能合约实现隐蔽通信
前端·npm·智能合约
java水泥工5 小时前
基于Echarts+HTML5可视化数据大屏展示-图书馆大屏看板
前端·echarts·html5
EndingCoder5 小时前
Electron 性能优化:内存管理和渲染效率
javascript·性能优化·electron·前端框架
半夏陌离5 小时前
SQL 实战指南:电商订单数据分析(订单 / 用户 / 商品表关联 + 统计需求)
java·大数据·前端
子兮曰5 小时前
🚀Vue3异步组件:90%开发者不知道的性能陷阱与2025最佳实践
前端·vue.js·vite
牛十二5 小时前
mac-intel操作系统go-stock项目(股票分析工具)安装与配置指南
开发语言·前端·javascript
whysqwhw5 小时前
Kuikly 扩展原生 API 的完整流程
前端