Skip to content

Array

[TOC]

索引

静态方法

  • Array.from()(arrayLike,mapFn?,thisArg?)静态方法,用于将类数组对象可迭代对象转换为真正的数组,并支持对元素进行映射处理。
  • Arrary.of()(el1, el2, ..., elN?)ES2015静态方法,用于创建包含可变数量参数的新数组,解决传统 Array() 构造函数在处理单个数值参数时的歧义问题
  • Array.isArray()(value)静态方法,用来判断一个变量是否为数组的方法。

属性

  • array.lengthnumber获取或设置数组的长度,直接反映数组中元素的数量(或最大索引加1)。

方法

构造方法

  • new Array()(),用于创建数组的构造函数。行为根据参数类型和数量的不同而变化,生成密集数组或稀疏数组。

修改原数组

  • arr.push()(el1, el2, ..., elN?)修改原数组,用于在数组的末尾添加一个或多个元素,并返回新的数组长度。
  • arr.pop()()修改原数组,用于移除数组的最后一个元素,并返回该元素的值。
  • arr.shift()()修改原数组,用于删除数组的第一个元素,并返回该元素,同时改变原数组的长度。
  • arr.unshift()(el1, el2, ..., elN?)修改原数组,用于在数组的开头添加一个或多个元素,并返回新的数组长度。
  • array.splice()(start,deleteCount?,item1?,item2?,...)修改原数组,可以删除、替换或添加元素。返回被删除的元素组成的数组。
  • arr.sort()(compareFn?)修改原数组,用于对数组的元素进行排序
  • arr.reverse()()修改原数组,用于将数组中的元素顺序颠倒的方法。
  • arr.fill()(value,start?,end?)修改原数组,用于填充数组。从 startend-1 的元素被替换为 value

访问方法

  • array.concat()(value1?, value2?, ...)纯函数,用于合并数组或值,返回新数组。
  • array.slice(start?,end?)纯函数,用于提取数组的一部分,返回新数组。
  • arr.join()(separator?)纯函数,用于将数组的元素连接成一个字符串
  • arr.at()(index?)ES2022,用于通过索引访问数组元素,支持负数索引。

搜索方法

  • arr.indexOf()(searchElement,fromIndex?),用于查找数组中指定元素的第一个匹配项的索引。若元素不存在,返回 -1
  • arr.lastIndexOf()(searchElement,fromIndex?),于从数组末尾向前搜索指定元素,返回元素最后一次出现的索引位置
  • arr.includes()(valueToFind,fromIndex?),用来判断数组是否包含某个元素,返回布尔值。
  • arr.find()(callbackFn,thisArg?)纯函数,用于查找数组中第一个满足条件的元素,返回该元素的值,若未找到则返回 undefined
  • arr.findIndex()(callbackFn,thisArg?)纯函数,用于查找数组中满足条件的第一个元素的索引,没有找到则返回-1

迭代方法

  • arr.forEach()(callbackFn,thisArg?),用于遍历数组中的每个元素,并对每个元素执行一个回调函数。
  • arr.map()(callbackFn,thisArg?)纯函数,用于对数组的每个元素执行转换操作,生成一个新数组
  • arr.filter()(callbackFn,thisArg?)纯函数,用于筛选数组元素,返回一个新数组,包含所有通过测试的元素
  • arr.reduce()(callbackFn,initialValue?),用于将数组元素依次累积处理,最终合并为单个值。
  • arr.some()(callbackFn,thisArg?)纯函数,用于检测数组中是否存在至少一个元素满足指定条件,返回布尔值。
  • arr.every()(callbackFn,thisArg?)纯函数,用于检测数组中的所有元素是否都满足指定条件,返回布尔值。

扁平化方法

  • arr.flat()(depth?)ES2019纯函数,用于将嵌套的多维数组“拉平”为一维或多维数组,返回一个新数组。
  • arr.flatMap()(callback,thisArg?)ES2019,将映射(map)和扁平化(flat)操作合并为一步

迭代器方法

  • arr.entries()(),用来返回一个新的数组迭代器对象,包含数组中每个索引的键值对
  • arr.keys()()ES2015,用来获取数组索引的迭代器
  • arr.values()()ES2015,用来获取数组元素值的迭代器

Array

属性

length@

array.lengthnumber获取或设置数组的长度,直接反映数组中元素的数量(或最大索引加1)。

语法

js
// 1. 获取数组长度
const len = array.length;

// 2. 设置数组长度
array.length = newLength;

核心行为

  1. 获取长度:返回数组的最大索引加1,包括稀疏数组的空位。

    js
    const sparseArr = [1, , 3]; // 稀疏数组(索引1为空位)
    console.log(sparseArr.length); // 3(最大索引2 + 1)
  2. 设置长度

    • 缩短数组(新长度 < 当前长度):超出新长度的元素会被删除,数组被截断。

      js
      const arr = [1, 2, 3, 4, 5];
      arr.length = 3;
      console.log(arr); // [1, 2, 3]
    • 扩展数组(新长度 > 当前长度):新增的索引位置会被填充为 空位(非 undefined,属于稀疏数组)。

      js
      const arr = [1, 2];
      arr.length = 5;
      console.log(arr); // [1, 2, empty × 3]

参数处理规则

  1. 数值转换:非数值类型会被转换为数值:

    js
    arr.length = "3";    // 转换为 3
    arr.length = "3.5";  // 转换为 3.5 → 取整为3(部分环境可能抛出错误)
    arr.length = null;   // 转换为 0
    arr.length = true;   // 转换为 1
    arr.length = "abc";  // 转换为 NaN → 视为0(清空数组)
  2. 有效性检查

    • 合法范围0 ≤ newLength ≤ 2^32 - 1(即 4294967295)。

    • 非法值处理

      • 负数:抛出 RangeError

        js
        arr.length = -1; // RangeError: Invalid array length
      • 非整数(如 3.5):部分环境静默取整,部分抛出错误(建议避免)。

        js
        arr.length = 3.5; // 可能设置为3或抛出错误(依环境而定)
      • 超出 2^32 - 1:抛出 RangeError

        js
        arr.length = 4294967296; // RangeError

注意事项

  1. 稀疏数组的影响:扩展后的空位可能被部分数组方法(如 mapforEach)跳过,导致意外行为。

    js
    const arr = [];
    arr.length = 3;
    arr.forEach((v, i) => console.log(i)); // 无输出(空位被跳过)
  2. 快速清空数组:设置 length = 0 是清空数组的高效方法。

    js
    const arr = [1, 2, 3];
    arr.length = 0;
    console.log(arr); // []
  3. 不可逆操作:缩短数组会永久删除超出新长度的元素,无法恢复。

静态方法

from()@

Array.from()(arrayLike,mapFn?,thisArg?)静态方法,用于将类数组对象可迭代对象转换为真正的数组,并支持对元素进行映射处理。

  • arrayLikeArrayLike|Iterator,待转换的类数组对象或可迭代对象。

  • mapFn?(item,index)=>newItem,对每个元素进行处理的回调函数。返回处理后的新元素,组成最终数组。

  • thisArg?any,执行 mapFn 时的 this 值。若 mapFn 是箭头函数,此参数无效。

  • 返回:

  • arrArray,转换后的数组实例。

核心功能

  1. 转换类数组对象

    js
    // 1. 转换 arguments 对象
    function example() {
      return Array.from(arguments); 
    }
    console.log(example(1, 2, 3)); // [1, 2, 3]
    
    // 2. 转换 NodeList
    const divs = document.querySelectorAll('div');
    const divArray = Array.from(divs); // 转为数组后可调用数组方法
  2. 转换可迭代对象

    js
    // 1. 转换 Set
    const set = new Set([1, 2, 3]);
    console.log(Array.from(set)); // [1, 2, 3]
    
    // 2. 转换字符串
    console.log(Array.from('Hello')); // ['H', 'e', 'l', 'l', 'o']
  3. 使用映射函数

    js
    // 1. 生成数字范围并加倍
    const nums = Array.from({ length: 5 }, (v, i) => i * 2);
    console.log(nums); // [0, 2, 4, 6, 8]
    
    // 2. 转换对象属性并处理
    const obj = { 0: 'a', 1: 'b', length: 2 };
    const arr = Array.from(obj, (val) => val.toUpperCase());
    console.log(arr); // ['A', 'B']

边界情况

  1. 原始值处理

    js
    Array.from(123);        // [](数字不可迭代)
    Array.from(true);       // [](布尔值不可迭代)
  2. 稀疏数组处理

    js
    Array.from({ length: 3 }); // [undefined, undefined, undefined]
  3. 映射函数参数

    js
    Array.from([1, 2, 3], function(v, i) { 
      return v + this.num; 
    }, { num: 10 }); // [11, 12, 13]

对比扩展运算符

场景Array.from()扩展运算符 [...]
类数组对象(无迭代器)✅ 支持(如 {length: 2}❌ 报错(需对象可迭代)
可迭代对象✅ 支持(如 Set、Map、字符串)✅ 支持
映射处理✅ 支持(通过 mapFn 参数)❌ 需额外调用 .map()

of()

Arrary.of()(el1, el2, ..., elN?)ES2015静态方法,用于创建包含可变数量参数的新数组,解决传统 Array() 构造函数在处理单个数值参数时的歧义问题

  • el1, el2, ..., elN?any,成为新数组的元素。

  • 返回:

  • arrarray,返回包含传入的所有参数作为元素的数组。

核心特性

  1. 解决 Array() 构造函数歧义

    传统 Array() 构造函数在单个数值参数时会创建稀疏数组,而 Array.of() 总是创建包含实际元素的数组:

    js
    // 传统 Array 构造函数的问题
    new Array(3);      // [empty × 3](稀疏数组)
    new Array("3");    // ["3"](单元素数组)
    
    // Array.of() 的一致行为
    Array.of(3);       // [3](单元素数组)
    Array.of("3");     // ["3"](单元素数组)
  2. 参数处理规则

    • 空参数:创建空数组

      js
      Array.of(); // []
    • 混合类型参数:保留所有类型

      js
      Array.of(1, "a", true, null, {x: 1}, [2]); 
      // [1, "a", true, null, {x:1}, [2]]
    • 特殊值处理

      js
      Array.of(undefined);   // [undefined]
      Array.of(null);        // [null]
      Array.of(NaN);         // [NaN]
  3. 对比相关方法

    方法Array(3)Array.of(3)[3]Array.from({length:3})
    结果[,,][3][3][undefined, undefined, undefined]
    长度3113
    稀疏性

isArray()@

Array.isArray()(value)静态方法,用来判断一个变量是否为数组的方法。

  • valueany,待检测的值,判断其是否为数组。

  • 返回:

  • isArrayboolean,返回是否为数组。

核心特性

  1. 底层原理

    Array.isArray() 通过检查对象的内部 [[Class]] 属性(或 ES6+ 的 Symbol.toStringTag)是否为 "Array",从而实现精确判断。

    等价于

    js
    function isArray(value) {
      return Object.prototype.toString.call(value) === '[object Array]';
    }
  2. 跨执行环境检测:

    若数组来自不同的全局环境(如 iframe),instanceof Array 可能失效,但 Array.isArray() 仍可靠。

    js
    // 假设 iframe 中的数组传入父页面
    const iframeArr = frame.contentWindow.document.createElement('div').children;
    console.log(Array.isArray(iframeArr)); // false(HTMLCollection 不是数组)
    console.log(iframeArr instanceof Array); // 可能因全局环境不同返回 false

示例

  1. 基本用法

    js
    // 数组
    Array.isArray([]);          // true
    Array.isArray([1, 2, 3]);    // true
    Array.isArray(new Array());  // true
    
    // 非数组
    Array.isArray({});           // false(普通对象)
    Array.isArray("[]");         // false(字符串)
    Array.isArray(123);          // false(数值)
    Array.isArray(null);         // false(null)
    Array.isArray(undefined);    // false(undefined)
    
    // 类数组对象
    Array.isArray({ 0: "a", length: 1 }) // false(类数组对象)

方法

构造函数

new Array()

new Array()(),用于创建数组的构造函数。行为根据参数类型和数量的不同而变化,生成密集数组或稀疏数组。

  • 返回:

  • arrarray数组实例,无论参数如何,始终返回一个数组对象。

语法

js
// 构造函数形式
const arr1 = new Array();        // 空数组
const arr2 = new Array(length);  // 指定长度的稀疏数组
const arr3 = new Array(elem1, elem2, ..., elemN); // 包含元素的数组

// 字面量等价形式(推荐)
const arr4 = [];                 // 空数组
const arr5 = [elem1, elem2];     // 包含元素的数组

核心特性

  1. 参数类型

    1. 无参数:创建空数组(length0)。

      js
      const arr = new Array(); // []
    2. 单个数值参数:创建长度为该数值的稀疏数组(空位填充)。

      js
      const sparseArr = new Array(3); 
      console.log(sparseArr);        // [empty × 3]
      console.log(sparseArr.length); // 3

      特殊值处理

      • 负数 → 抛出 RangeError

        js
        new Array(-1); // RangeError: Invalid array length
      • 非整数(如 2.5)→ 抛出 RangeError(部分环境可能静默截断,但应避免)。

    3. 多个参数或非数值参数:创建一个数组,元素为传入的参数。

      js
      new Array(1, 2, 3);        // [1, 2, 3]
      new Array("a", {x: 1});     // ["a", {x: 1}]
      new Array(true, null);      // [true, null]
  2. 稀疏数组陷阱

    • 通过 new Array(length) 创建的数组元素为空位(非 undefined)。
    • 访问空位返回 undefined,但属性未被实际定义(in 操作符检测为 false)。
    js
    const arr = new Array(3);
    console.log(arr[0]);        // undefined
    console.log(0 in arr);      // false(空位)

进阶扩展

  1. 单个数值参数的歧义问题

    js
    // 数值参数 → 创建稀疏数组
    const arr1 = new Array(3); // [empty × 3]
    
    // 非数值参数 → 创建单元素数组
    const arr2 = new Array("3"); // ["3"]

    解决:使用 Array.of() 可以解决 new Array() 单个数值参数的歧义问题:

    js
    Array.of(3);       // [3](直接包含元素3)
    new Array(3);      // [empty × 3](长度为3的稀疏数组)
  2. 避免稀疏数组

    问题:使用 new Array(length) 生成的稀疏数组可能导致意外行为(如 forEachmap 跳过空位)。

    js
    const sparse = new Array(3);
    sparse[1] = 10;
    console.log(sparse); // [empty, 10, empty]
    console.log(sparse.map(v => v * 2)); // [empty, 20, empty](map 跳过空位)

    替代方案:使用 Array.from({ length: 3 }) 生成密集数组(填充 undefined)

    js
    // 生成密集数组(填充 undefined)
    const dense = Array.from({ length: 3 }); // [undefined, undefined, undefined]
    const dense2 = [...new Array(3)];        // [undefined, undefined, undefined]
  3. 优先使用字面量 []

    • 更简洁[]new Array() 更高效且可读。
    • 避免歧义new Array(3)[3] 结果完全不同。

修改原数组

push()

arr.push()(el1, el2, ..., elN?)修改原数组,用于在数组的末尾添加一个或多个元素,并返回新的数组长度。

  • el1, el2, ..., elN?any,要添加到数组末尾的一个或多个元素。

  • 返回:

  • lengthnumber,返回添加元素后数组的 length 属性值。

核心特性

  1. 直接修改原数组

    push() 会改变原数组,若需保留原数组,使用展开运算符或 concat()

    js
    const newArr = [...oldArr, newElement]; // 创建新数组
  2. 引用类型元素

    添加对象或数组时,保存的是引用(修改引用对象会影响数组内容)。

    js
    const obj = { x: 1 };
    const arr = [];
    arr.push(obj);
    obj.x = 2;
    console.log(arr[0].x); // 2
  3. 性能优化

    • 添加多个元素时,一次性 push() 比多次调用更高效。
    • 避免在循环中高频调用 push(),可考虑批量处理。

示例

  1. 添加单个或多个元素

    js
    const arr = [1, 2];
    const newLength = arr.push(3, 4); 
    console.log(arr);        // [1, 2, 3, 4]
    console.log(newLength);  // 4
  2. 添加数组或对象

    js
    const arr = ["a"];
    arr.push([1, 2], { x: 1 }); 
    console.log(arr); // ["a", [1, 2], { x: 1 }](数组作为单个元素添加)
  3. 空参数调用

    js
    const arr = [1, 2];
    console.log(arr.push()); // 2(数组未修改,返回原长度)
pop()

arr.pop()()修改原数组,用于移除数组的最后一个元素,并返回该元素的值。

  • 返回:

  • lastElany|undefined,返回值:

    • 如果数组 非空:返回数组的最后一个元素。
    • 如果数组 为空:返回 undefined

核心特性

  1. 直接修改原数组

    pop() 是原地操作,无返回值副本。需谨慎在需要保留原数组的场景中使用。

  2. 性能优化

    • 尾部操作高效pop() 的时间复杂度为常数时间(O(1)),适合频繁删除末尾元素。
    • 头部操作低效:若需频繁删除头部元素,建议使用 shift() 或考虑数据结构替换(如链表)。
  3. 稀疏数组

    空位(未被赋值的索引)不会影响 pop() 的行为,仅移除最后一个有效元素。

    js
    const sparseArr = [1, , 3]; // 索引1为空位
    sparseArr.pop();            // 移除3 → [1, empty]

示例

  1. 移除并返回最后一个元素

    js
    const fruits = ["apple", "banana", "orange"];
    const lastFruit = fruits.pop();
    
    console.log(fruits);    // ["apple", "banana"]
    console.log(lastFruit); // "orange"

进阶扩展

  1. 循环清空数组

    通过循环 pop() 逐步清空数组。

    js
    while (arr.length > 0) {
      arr.pop();
    }
shift()

arr.shift()()修改原数组,用于删除数组的第一个元素,并返回该元素,同时改变原数组的长度。

  • 返回:

  • firstElany|undefined,返回被移除的数组的第一个元素;如果数组为空返回undefined

核心特性

  1. 修改原数组

    直接删除数组的第一个元素,数组长度减 1,后续元素向前移动一位。

  2. 性能问题

    • 头部操作低效shift() 的时间复杂度为线性时间(O(n)),因为需要移动所有剩余元素。
    • 大型数组慎用:频繁调用可能导致性能瓶颈,可考虑反向操作(先 reverse()pop())或使用链表。
  3. 稀疏数组空位处理

    若第一个元素是空位(未被赋值),shift() 返回 undefined,但空位会被移除。

    js
    const arr = [, , 3];
    console.log(arr.shift()); // undefined(移除第一个空位)
    console.log(arr);         // [empty, 3](长度减1)
  4. 引用类型元素

    移除对象时返回的是原引用,修改会影响原对象。

    js
    const obj = { x: 1 };
    const arr = [obj];
    const removedObj = arr.shift();
    removedObj.x = 2;
    console.log(obj.x); // 2(原对象被修改)

示例

  1. 移除并返回第一个元素

    js
    const fruits = ["apple", "banana", "orange"];
    const firstFruit = fruits.shift();
    
    console.log(fruits);    // ["banana", "orange"]
    console.log(firstFruit); // "apple"
unshift()

arr.unshift()(el1, el2, ..., elN?)修改原数组,用于在数组的开头添加一个或多个元素,并返回新的数组长度。

  • el1, el2, ..., elN?any,要添加到数组开头的一个或多个元素。

  • 返回:

  • lengthnumber,返回添加元素后数组的 length 属性值。

核心特性

  1. 直接修改原数组

    unshift() 会改变原数组,若需保留原数组,使用展开运算符或 concat()

    js
    const newArr = [newElement, ...oldArr]; // 创建新数组
  2. 引用类型元素

    添加对象或数组时,保存的是引用(修改引用对象会影响数组内容)。

    js
    const obj = { x: 1 };
    const arr = [];
    arr.unshift(obj);
    obj.x = 2;
    console.log(arr[0].x); // 2
  3. 链式调用限制

    unshift() 返回新长度,无法直接链式调用数组方法。

    js
    [1, 2].unshift(3).map(x => x * 2); // 报错:length.map 不存在
  4. 性能问题

    • 头部操作低效shift() 的时间复杂度为线性时间(O(n)),因为需要移动所有剩余元素。
    • 大型数组慎用:频繁调用可能导致性能瓶颈,可考虑反向操作(先 reverse()pop())或使用链表。
    js
    // 频繁 unshift 大型数组可能导致性能问题(时间复杂度 O(n))
    const largeArr = new Array(1e6).fill(0);
    largeArr.unshift(1); // 需要移动所有元素,效率低

示例

  1. 数组头部添加元素

    js
    const arr = [3, 4];
    const newLength = arr.unshift(1, 2); 
    console.log(arr);        // [1, 2, 3, 4]
    console.log(newLength);  // 4
  2. 添加数组或对象

    js
    const arr = ["a"];
    arr.unshift([1, 2], { x: 1 }); 
    console.log(arr); // [[1, 2], { x: 1 }, "a"](数组作为单个元素添加)
  3. 空参数调用

    js
    const arr = [1, 2];
    console.log(arr.unshift()); // 2(数组未修改,返回原长度)
splice()@

array.splice()(start,deleteCount?,item1?,item2?,...)修改原数组,可以删除、替换或添加元素。返回被删除的元素组成的数组。

  • startnumber,开始修改的索引(从 0 开始)。

    • start < 0:从数组末尾倒数(例如,-2 表示倒数第二个元素)。

    • start < -数组长度:视为 0。

    • start >= 数组长度:从数组末尾开始操作(直接添加元素到末尾)。

  • deleteCount?number默认:0,要删除的元素数量。

    • deleteCount <= 0:不删除元素(若未提供,则删除从 start 到末尾的所有元素)。

    • deleteCount > 剩余元素数:删除从 start 到末尾的所有元素。

  • item1?,item2?,...any,从 start 位置开始插入的元素。如果不提供此参数,则仅删除元素。

  • 返回:

  • deleteArrArray,返回被删除的元素组成的数组。

核心功能

  1. 删除元素

    js
    const arr = [1, 2, 3, 4, 5];
    arr.splice(1, 2); // 从索引1开始删除2个元素
    console.log(arr); // [1, 4, 5]
    console.log(返回值); // [2, 3]
  2. 添加元素

    js
    const arr = [1, 2, 3];
    arr.splice(1, 0, "a", "b"); // 从索引1开始添加元素,不删除
    console.log(arr); // [1, "a", "b", 2, 3]
  3. 替换元素

    js
    const arr = [1, 2, 3];
    arr.splice(1, 1, "x"); // 删除索引1的1个元素,插入"x"
    console.log(arr); // [1, "x", 3]
    console.log(返回值); // [2]

边界情况

  1. 稀疏数组:空位会被跳过或处理为 undefined(取决于具体操作)。
sort()

arr.sort()(compareFn?)修改原数组,用于对数组的元素进行排序

  • compareFn?(a,b)=>number,定义排序顺序的比较逻辑。

    • aany,当前比较的第一个元素。

    • bany,当前比较的第二个元素。

    • 返回:

    • resultnumber,返回值:

      • 负数a 排在 b 前面。

      • ab 顺序不变(ES2019+ 保证稳定排序)。

      • 正数b 排在 a 前面。

  • 返回:

  • sortedArrarray,返回排序后的原数组的引用。

核心特性

  1. 默认排序(无参数)

    将元素转换为字符串,按 Unicode 码点升序排列。

    js
    [10, 2, 1].sort();          // [1, 10, 2](字符串比较)
    ["Banana", "apple"].sort(); // ["Banana", "apple"](Unicode 大小写敏感)
  2. 自定义比较函数

    • 数字升序

      js
      [10, 2, 1].sort((a, b) => a - b); // [1, 2, 10]
    • 数字降序

      js
      [10, 2, 1].sort((a, b) => b - a); // [10, 2, 1]
    • 对象属性排序

      js
      const users = [
        { name: "Alice", age: 25 },
        { name: "Bob", age: 30 },
        { name: "Charlie", age: 20 },
      ];
      users.sort((a, b) => a.age - b.age); // 按 age 升序排列
  3. 字符串本地化排序

    使用 localeCompare() 按语言规则排序:

    js
    ["ä", "a", "z"].sort((a, b) => a.localeCompare(b)); // ["a", "ä", "z"](德语环境)
  4. 稀疏数组

    空位(empty slots)被视为 undefined,排序到数组末尾:

    js
    const sparse = [1, , 3];
    sparse.sort(); // [1, 3, empty](空位被保留在末尾)
  5. 稳定性(ES2019+)

    相同排序键的元素保持原有相对顺序:

    js
    const arr = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 25 },
    ];
    arr.sort((a, b) => a.age - b.age);
    // Alice 和 Bob 的相对顺序不变(稳定排序)

示例

  1. 多条件排序

    js
    const tasks = [
      { priority: 2, title: "Task B" },
      { priority: 1, title: "Task A" },
      { priority: 2, title: "Task C" },
    ];
    tasks.sort((a, b) => {
      if (a.priority !== b.priority) {
        return a.priority - b.priority; // 按 priority 升序
      } else {
        return a.title.localeCompare(b.title); // priority 相同按 title 排序
      }
    });
  2. 逆序排序

    js
    const letters = ["a", "b", "c"];
    letters.sort((a, b) => -1); // 所有元素逆序 → ["c", "b", "a"]
  3. 随机排序

    js
    const arr = [1, 2, 3, 4, 5];
    arr.sort(() => Math.random() - 0.5); // 随机打乱数组(非均匀分布,慎用)

注意事项

  1. 原地排序

    sort() 直接修改原数组,若需保留原数组,需先复制:

    js
    const sorted = [...array].sort();
  2. 比较函数必须返回数值

    返回非数值(如布尔值)可能导致意外结果:

    js
    [1, 2, 3].sort(() => true); // 可能不会按预期排序(true → 1,false → 0)
  3. 性能与复杂度

    • 时间复杂度通常为 O(n log n)
    • 对大型数组(如超过10^5元素)需谨慎使用。
reverse()

arr.reverse()()修改原数组,用于将数组中的元素顺序颠倒的方法。

  • 返回:

  • arrarray,返回反转后的原数组的引用。

核心特性

  1. 元素交换规则

    • 第一个元素与最后一个元素交换,第二个与倒数第二个交换,依此类推。

    • 稀疏数组的空位位置不变,仅调整已赋值元素的索引。

      js
      const sparseArr = [1, , 3]; // 索引1为空位
      sparseArr.reverse();
      console.log(sparseArr); // [3, empty, 1](空位位置保留)
  2. 性能问题

    • 时间复杂度为 O(n),需遍历半数元素进行交换。
    • 对超大型数组(如百万级元素)需谨慎使用,可能影响性能。
  3. 类数组对象支持

    可通过 callapplyreverse() 应用于非数组对象(需包含 length 属性)。

    js
    const nodeList = document.querySelectorAll("div");
    Array.prototype.reverse.call(nodeList); // 反转元素集合

示例

  1. 基本用法

    js
    const arr = [1, 2, 3];
    arr.reverse();
    console.log(arr); // [3, 2, 1](原数组被修改)
  2. 不修改原数组

    使用 slice().reverse() 可以保留原数组,仅获取反转副本

    js
    const arr = [1, 2, 3];
    arr.slice().reverse();
    console.log(arr); // [1, 2, 3](原数组被修改)
fill()

arr.fill()(value,start?,end?)修改原数组,用于填充数组。从 startend-1 的元素被替换为 value

  • valueany,填充数组元素的值。

  • start?number默认:0,填充开始索引,会转换为整数,支持负数索引。

  • end?number默认:array.length,填充结束索引(不包含该位置),会转换为整数,支持负数索引。

  • 返回:

  • newArrarray,返回修改后的原数组。

核心特性

  1. 直接修改原数组

    fill() 是原地操作,不会生成新数组。

    js
    const arr = [1, 2, 3];
    const newArr = arr.fill(0);
    console.log(arr === newArr); // true
  2. 填充引用类型

    value 是对象,所有填充元素共享同一引用

    js
    const arr = new Array(2).fill({});
    arr[0].x = 1;
    console.log(arr[1].x); // 1(所有元素指向同一对象)
  3. 替代方案(生成新数组)

    使用 Array.from()map() 避免修改原数组

    js
    const newArr = Array.from({ length: 3 }, () => "a"); // ["a", "a", "a"]

示例

  1. 基本填充

    js
    const arr = [1, 2, 3, 4, 5];
    arr.fill(0);        // 所有元素变为0 → [0, 0, 0, 0, 0]
    arr.fill("a", 1, 3);// 索引1到2填充为"a" → [0, "a", "a", 0, 0]
    
    // 负数索引
    arr.fill(0, -3, -1); // 倒数第3到倒数第2(索引2到3)填充 → [1, 2, 0, 0, 5]
    
    // 非整数参数
    arr.fill("x", 1.5, 2.9); // start=1(取整),end=2(取整) → [1, "x", 3, 4, 5]
    
    // 超出数组长度:不填充
    arr.fill(0, 6);     // start ≥ 数组长度 → 不填充,返回 [1, 2, 3, 4, 5]
  2. 填充稀疏数组

    js
    const sparse = new Array(3); // [empty × 3]
    sparse.fill(1);             // 所有空位填充为1 → [1, 1, 1]

访问方法

concat()

array.concat()(value1?, value2?, ...)纯函数,用于合并数组或值,返回新数组。

  • value1?, value2?, ...any,待合并的值,可以是数组、原始值、对象等。不同类型的处理规则不同:

    • 数组:将数组的每个元素(仅展开一层)添加到新数组。

    • 非数组:直接作为单个元素添加到新数组(包括nullundefinedSymbol类数组对象)。

  • 返回:

  • arrArray,合并后的结果。参数为空执行浅拷贝。

核心行为

  1. 合并数组

    js
    const arr1 = [1, 2];
    const arr2 = [3, [4, 5]];
    const merged = arr1.concat(arr2); // [1, 2, 3, [4, 5]](仅展开一层)
  2. 合并非数组值

    js
    const arr = [1];
    const newArr = arr.concat("a", { x: 2 }, null); // [1, "a", {x: 2}, null]
  3. 空参数

    js
    const arr = [1, 2];
    const copy = arr.concat(); // [1, 2](copy !== arr) 原数组的浅拷贝
  4. 稀疏数组

    js
    const sparseArr = [1, , 3]; // 空位在索引1
    const newArr = sparseArr.concat([4, 5]); // [1, empty, 3, 4, 5](保留空位)
  5. 类数组对象

    js
    const arrayLike = { 0: "a", length: 1 };
    const arr = [1].concat(arrayLike); // [1, {0: "a", length: 1}](不展开类数组对象)

注意事项

  1. 性能优化:合并大型数组时,concat() 可能比循环遍历更高效,但需注意内存占用。

  2. 替代方案:使用扩展运算符实现类似效果(仅限可迭代对象):

    js
    const merged = [...arr1, ...arr2, value];
slice()@

array.slice(start?,end?)纯函数,用于提取数组的一部分,返回新数组。

  • start?number默认:0,开始提取的索引(从 0 开始)。

    • start < 0:从数组末尾倒数(例如,-2 表示倒数第二个元素)。

    • start >= 数组长度:返回空数组。

  • end?number默认:数组长度,结束提取的索引(不包含该位置)。

    • end < 0:从数组末尾倒数。

    • end <= start:返回空数组。

  • 返回:

  • arrArray,包含从 start 到 end(不含 end)的元素。

边界情况

  1. 稀疏数组:空位保留(如 [1, ,3].slice(0,3)[1, empty, 3])。

示例

  1. 基本使用

    js
    const arr = [1, 2, 3, 4, 5];
    
    console.log(arr.slice(1, 3));    // [2, 3](索引1到2)
    console.log(arr.slice(-3, -1));  // [3, 4](倒数第三到倒数第二个)
    console.log(arr.slice(2));       // [3, 4, 5](索引2到末尾)
    console.log(arr.slice());        // [1, 2, 3, 4, 5](浅拷贝原数组)
join()

arr.join()(separator?)纯函数,用于将数组的元素连接成一个字符串

  • separator?any默认:,,字符串分割符。隐式转换为字符串。

  • 返回:

  • strstring,数组所有元素转换为字符串后,用 separator 连接的结果。

  • 特殊情况

    • 空数组:返回空字符串 ""
    • 单个元素:直接返回该元素的字符串形式,无分隔符。
    • 稀疏数组:空位视为空字符串,按位置插入分隔符。

核心特性

  1. 处理特殊值

    nullundefined:转换为空字符串。

    js
    [1, null, undefined, 4].join(); // "1,,,4"

    对象:调用 toString() 方法。

    js
    [{}].join(); // "[object Object]"

    稀疏数组:空位视为空字符串,按位置插入分隔符。

    js
    new Array(3).join("a"); // "aa"(3个空位 → 两个分隔符)
    [1, , 3].join();        // "1,,3"(空位视为空字符串)

示例

  1. 基本用法

    js
    [1, 2, 3].join();          // "1,2,3"(默认逗号分隔)
    ["a", "b", "c"].join("-"); // "a-b-c"
  2. 复杂类型处理

    js
    const mixed = [1, { name: "Alice" }, [2, 3], () => {}];
    console.log(mixed.join(" | "));
    // "1 | [object Object] | 2,3 | () => {}"
at()

arr.at()(index?)ES2022,用于通过索引访问数组元素,支持负数索引。

  • index?number默认:0,要返回的数组元素的索引,会被转换为整数,支持负数索引。

  • 返回:

  • elany|undefined,返回值:

    • any:若 index 在有效范围内,返回对应位置的元素的值。
    • undefined:若 index 超出数组范围(正数 ≥ 数组长度 或 负数绝对值 > 数组长度)。

核心特性

  1. 对比 array[index]

    场景array.at(index)array[index]
    支持负数索引✅(如 arr.at(-1)❌(arr[-1]undefined
    非数值参数处理✅ 隐式转换为整数✅ 隐式转换为字符串(可能意外匹配属性)
    代码可读性✅ 更直观(语义明确)❌ 需额外处理负数逻辑

示例

  1. 基本用法

    js
    const arr = [5, 12, 8, 130, 44];
    
    console.log(arr.at(2));    // 8(正数索引)
    console.log(arr.at(-1));   // 44(负数索引)
    console.log(arr.at());     // 5(默认 index=0)
    
    // 超出范围
    console.log(arr.at(5));    // undefined(超出正向范围)
    console.log(arr.at(-6));   // undefined(超出逆向范围)
    
    // 参数隐式转换
    console.log(arr.at("1"));  // 12(字符串 "1" → 1)
    console.log(arr.at("2.5"));// 8(字符串 "2.5" → 2)
    console.log(arr.at("abc"));// 5("abc" → NaN → 0)
    console.log(arr.at(null)); // 5(null → 0)
  2. 结合可选链操作符使用

    避免中间结果为 undefined 导致的错误

    js
    // 避免中间结果为 undefined 导致的错误
    const safeValue = array.at?.(-1)?.property; // 可选链操作符结合使用
  3. 处理类数组对象

    js
    const arrayLike = { 0: "a", 1: "b", length: 2 };
    console.log(Array.prototype.at.call(arrayLike, -1)); // "b"

搜索方法

indexOf()

arr.indexOf()(searchElement,fromIndex?),用于查找数组中指定元素的第一个匹配项的索引。若元素不存在,返回 -1

  • searchElementany,要查找的目标元素。使用 严格相等(=== 进行匹配(对象比较引用地址)。

  • fromIndex?number默认:0,开始搜索的索引,会转换为整数,支持负数索引。

  • 返回:

  • indexnumber,找到返回第一个匹配元素的索引;未找到返回 -1

核心特性

  1. NaN 无法匹配

    替代方案:使用 includes() 或用 findIndex(Number.isNaN) 处理

    js
    const arr = [NaN, 1, "NaN"];
    console.log(arr.indexOf(NaN));         // -1(严格相等无法匹配 NaN)
    
    // 替代方案
    console.log(arr.includes(NaN));        // 0
    console.log(arr.findIndex(Number.isNaN)); // 0(需用 findIndex 处理)
  2. 稀疏数组跳过空位

    js
    const sparseArr = [1, , 3]; // 空位在索引1
    console.log(sparseArr.indexOf(undefined)); // -1(空位不会被显式处理)

示例

  1. 基本查找

    js
    const arr = ["apple", "banana", "orange", "banana"];
    console.log(arr.indexOf("banana"));    // 1(第一个匹配项)
    console.log(arr.indexOf("grape"));     // -1(未找到)
    
    // 指定起始位置
    const arr = [1, 2, 3, 2, 1];
    console.log(arr.indexOf(2, 2));        // 3(从索引2开始找到的2)
    console.log(arr.indexOf(1, -3));       // 4(倒数第3位是3,从索引2开始)
    
    // 对象引用比较
    const obj = { x: 1 };
    const arr = [obj, { x: 1 }];
    console.log(arr.indexOf(obj));         // 0(同一引用)
    console.log(arr.indexOf({ x: 1 }));    // -1(不同引用)
  2. 删除第一个匹配项

    js
    const arr = [10, 20, 30, 20];
    const index = arr.indexOf(20);
    if (index !== -1) arr.splice(index, 1);
    console.log(arr); // [10, 30, 20]
lastIndexOf()

arr.lastIndexOf()(searchElement,fromIndex?),于从数组末尾向前搜索指定元素,返回元素最后一次出现的索引位置

  • searchElementany,要查找的目标元素。使用 严格相等(=== 进行匹配(对象比较引用地址)。
  • fromIndex?number默认:array.length-1,从最后一个元素开始向前搜索,会转换为整数,支持负数索引。行为规则
    • 正数:作为搜索的起始索引(从该位置向前搜索)。
    • 负数:从数组末尾倒数的位置(如 -2 表示倒数第二个元素)。
    • 超出范围
      • fromIndex >= array.length → 搜索整个数组
      • fromIndex < 0 → 实际索引为 max(0, array.length + fromIndex)
  • 返回:
  • indexnumber,找到的目标元素最后一次出现的索引;未找到返回 -1

核心特性:类似 indexOf()

  1. 对比 indexOf()

    特性lastIndexOf()indexOf()
    搜索方向从后向前从前向后
    起始位置默认 arr.length - 1默认 0
    查找逻辑返回最后出现位置返回首次出现位置
    适用场景查找最新日志、最后操作记录等查找首次出现、存在性检查
  2. NaN 无法匹配

    替代方案:使用 includes() 或用 findIndex(Number.isNaN) 处理

    js
    const arr = [1, NaN, 3, NaN];
    console.log(arr.lastIndexOf(NaN)); // -1(严格相等无法匹配NaN)
    
    // 替代方案
    console.log(arr.includes(NaN));        // 1
    console.log(arr.findIndex(Number.isNaN)); // 1(需用 findIndex 处理)
  3. 稀疏数组跳过空位

    js
    const sparseArr = [1, , 3]; // 索引1为空位
    console.log(sparseArr.lastIndexOf(undefined)); // -1(空位不会被检测)
  4. 边界情况

    js
    const arr = [1, 2, 3, 2, 1];
    
    // 起始位置超出数组长度
    console.log(arr.lastIndexOf(1, 10)); // 4(搜索整个数组)
    
    // 负值超出范围
    console.log(arr.lastIndexOf(1, -10)); // 0(实际索引为0)
    
    // 起始位置为负数
    console.log(arr.lastIndexOf(2, -3)); // 1(倒数第3位是3,从索引2开始向前)
  5. 严格相等比较

    js
    ["1", 1].lastIndexOf(1); // 1(类型不同不匹配)
  6. 性能优化

    • 大型数组使用 lastIndexOf() 效率较低(O(n) 复杂度)
    • 如需高频查找,可考虑建立索引映射:
    js
    // 创建值到最后一个索引的映射
    const lastIndexMap = {};
    arr.forEach((item, index) => {
      lastIndexMap[item] = index; // 始终记录最后出现的索引
    });

示例

  1. 基本查找(从后向前)

    js
    const arr = [2, 5, 9, 2];
    console.log(arr.lastIndexOf(2));     // 3(最后一个2的索引)
    console.log(arr.lastIndexOf(7));     // -1(未找到)
    
    // 指定起始位置
    const arr = [2, 5, 9, 2];
    console.log(arr.lastIndexOf(2, 2));  // 0(从索引2开始向前找)
    console.log(arr.lastIndexOf(2, -2)); // 0(倒数第2位是9,从索引2开始)
    
    // 对象引用比较
    const obj = { id: 1 };
    const arr = [obj, { id: 1 }, obj];
    console.log(arr.lastIndexOf(obj));         // 2(同一引用)
    console.log(arr.lastIndexOf({ id: 1 }));   // -1(不同引用)
includes()@

arr.includes()(valueToFind,fromIndex?),用来判断数组是否包含某个元素,返回布尔值。

  • valueToFindany,要搜索的元素,比较逻辑为 严格相等(===

  • fromIndex?number默认:0,开始搜索的索引,会转换为整数,支持负索引。

    • 正数:从索引 fromIndex 开始向后搜索。

    • 负数:从 数组长度 + fromIndex 开始搜索(如 fromIndex = -2 表示从倒数第二个位置开始)。

    • 超出范围:若 fromIndex ≥ 数组长度,返回 false;若 fromIndex < -数组长度,从索引 0 开始搜索。

  • 返回:

  • isIncludeboolean,返回是否包含指定元素。

核心特性

  1. 特殊值处理

    NaN 可被检测:与 indexOf 不同,indexOf 无法检测 NaN

    js
    [NaN].includes(NaN); // true

    undefined 与空位:稀疏数组的空位被视为 undefined

    js
    [1, , 3].includes(undefined); // true
  2. 对象检测:引用比较

    js
    const obj = { x: 1 };
    [obj].includes(obj);        // true(同一引用)
    [{ x: 1 }].includes({ x: 1 }); // false(不同引用)
  3. 对比 indexOf()

    方法检测 NaN空位处理返回值语义清晰度
    includes()空位视为 undefined布尔值更直观(是/否)
    indexOf()跳过空位索引(无则 -1需额外判断

示例

  1. 基本搜索

    js
    const arr = [1, 2, 3, 4];
    console.log(arr.includes(3));     // true
    console.log(arr.includes(5));     // false
  2. 从指定位置搜索

    js
    const arr = ["a", "b", "c", "d"];
    console.log(arr.includes("a", 1));    // false(从索引1开始)
    console.log(arr.includes("c", -2));   // true(等效于索引2)
  3. 处理稀疏数组

    js
    const sparse = [1, , 3];
    console.log(sparse.includes(undefined)); // true
find()@

arr.find()(callbackFn,thisArg?)纯函数,用于查找数组中第一个满足条件的元素,返回该元素的值,若未找到则返回 undefined

  • callbackFn(el,index?,arr?)=>boolean,定义查找条件,对每个元素执行一次,直到找到匹配项。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 find() 的原数组。

    • 返回:

    • resultboolean,返回值:

      • true:找到匹配元素,立即停止遍历并返回该元素。

      • false:继续查找下一个元素。

  • thisArg?any默认:undefined,指定 callbackFn 中的 this 值。

  • 返回:

  • isFindany|undefined,返回值:

    • 匹配的元素:第一个满足条件的元素值。
    • 未找到undefined

核心特性

  1. 特殊规则

    • 稀疏数组:空位会被跳过(不会触发回调)。

      js
      const sparseArr = [1, , 3]; // 空位在索引1
      const found = sparseArr.find(num => num === undefined);
      console.log(found); // undefined(空位未触发回调,实际检测元素为1和3)
    • 中途终止:一旦找到匹配项,立即停止遍历。

  2. 严格匹配逻辑

    条件判断需明确,避免因隐式转换导致意外结果。

    js
    // 隐性布尔转换示例
    [0, 1, 2].find(num => num); // 1(0 视为 false,1 视为 true)

示例

  1. 查找基本类型元素

    js
    const nums = [5, 12, 8, 130, 44];
    const found = nums.find(num => num > 10);
    console.log(found); // 12(第一个大于10的元素)
  2. 查找对象数组元素

    js
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 17 },
      { name: "Charlie", age: 30 },
    ];
    const adult = users.find(user => user.age >= 18);
    console.log(adult); // { name: "Alice", age: 25 }
  3. 使用 thisArg 绑定上下文

    js
    class Checker {
      constructor(threshold) {
        this.threshold = threshold;
      }
      isOver(num) {
        return num > this.threshold;
      }
    }
    const checker = new Checker(10);
    const nums = [5, 12, 8];
    const result = nums.find(function(num) {
      return this.isOver(num); // this 指向 checker 实例
    }, checker);
    console.log(result); // 12
findIndex()@

arr.findIndex()(callbackFn,thisArg?)纯函数,用于查找数组中满足条件的第一个元素的索引,没有找到则返回-1

  • callbackFn(el,index?,arr?)=>boolean,定义查找条件,对每个元素执行一次,直到找到匹配项。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 findIndex() 的原数组。

    • 返回:

    • resultboolean,返回值:

      • true:找到匹配元素,立即停止遍历并返回当前索引。

      • false:继续查找下一个元素。

  • thisArg?any默认:undefined,指定 callbackFn 中的 this 值。

  • 返回:

  • isFindany|undefined,返回值:

    • 匹配的索引:第一个满足条件的元素索引(从 0 开始)。
    • 未找到-1

核心特性

  1. 特殊规则

    • 稀疏数组:空位会被跳过(不会触发回调)。

      js
      const sparseArr = [1, , 3]; // 空位在索引1
      const index = sparseArr.findIndex(num => num === undefined);
      console.log(index); // -1(空位未触发回调,实际检测元素为1和3)
    • 中途终止:一旦找到匹配项,立即停止遍历。

  2. 严格条件判断

    回调函数需明确返回布尔值,避免隐式转换导致误判。

    js
    [0, 1, 2].findIndex(num => num); // 1(0视为false,1视为true)

示例

  1. 查找基本类型元素

    js
    const nums = [5, 12, 8, 130, 44];
    const index = nums.findIndex(num => num > 10);
    console.log(index); // 1(第一个大于10的元素是12,索引为1)
  2. 未找到匹配元素

    js
    const emptyResult = [1, 2, 3].findIndex(num => num > 5);
    console.log(emptyResult); // -1
  3. 查找对象数组元素

    js
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 17 },
      { name: "Charlie", age: 30 },
    ];
    const adultIndex = users.findIndex(user => user.age >= 18);
    console.log(adultIndex); // 0(Alice的索引)
  4. 使用 thisArg 绑定上下文

    js
    class Checker {
      constructor(threshold) {
        this.threshold = threshold;
      }
      isOver(num) {
        return num > this.threshold;
      }
    }
    const checker = new Checker(10);
    const nums = [5, 12, 8];
    const index = nums.findIndex(function(num) {
      return this.isOver(num); // this 指向 checker 实例
    }, checker);
    console.log(index); // 1(12的索引)
  5. 箭头函数无法绑定 thisArg

    js
    // 箭头函数忽略 thisArg
    const nums = [1, 2, 3];
    const index = nums.findIndex((num) => num === this.value, { value: 2 });
    console.log(index); // -1(箭头函数无法绑定 thisArg)

迭代方法

forEach()@

arr.forEach()(callbackFn,thisArg?),用于遍历数组中的每个元素,并对每个元素执行一个回调函数。

  • callbackFn(el,index?,arr?),对数组中的每个元素执行的操作。

    • elany,当前处理的元素值。

    • index?number,当前元素的索引。

    • arr?array,调用 forEach() 的原数组。

  • thisArg?any默认:undefined,指定回调函数中的 this 值。

    • 注意:若使用箭头函数,此参数无效(箭头函数无自身 this)。
  • 返回:

  • resultundefinedforEach() 始终返回 undefined,仅用于遍历操作,不生成新数组。

核心特性

  1. 无法中断遍历

    即使回调函数中使用 returnthrow,遍历仍会继续。

    替代方案:使用 for 循环或 some()/every() 提前终止。

    js
    // return 无法终止遍历
    [1, 2, 3].forEach(num => {
      if (num === 2) return;
      console.log(num); // 1, 3(仍会输出3)
    });
  2. 异步操作问题

    forEach() 不会等待异步操作完成,可能导致意外结果。

    替代方案:使用 for...of 结合 await

    js
    // 异步示例(不推荐)
    [1, 2, 3].forEach(async num => {
      await new Promise(resolve => setTimeout(resolve, 100));
      console.log(num); // 可能乱序输出
    });

示例

  1. 遍历数组元素

    js
    const nums = [1, 2, 3];
    nums.forEach((num, index) => {
      console.log(`索引 ${index}: 值 ${num}`);
    });
    // 输出:
    // 索引 0: 值 1
    // 索引 1: 值 2
    // 索引 2: 值 3
  2. 修改原数组

    js
    const arr = [1, 2, 3];
    arr.forEach((num, index, array) => {
      array[index] = num * 2;
    });
    console.log(arr); // [2, 4, 6]
  3. 使用 thisArg 绑定上下文

    js
    class Counter {
      constructor() {
        this.count = 0;
      }
      increment() {
        this.count++;
      }
    }
    const counter = new Counter();
    [1, 2, 3].forEach(function() {
      this.increment(); // this 指向 counter 实例
    }, counter);
    console.log(counter.count); // 3
map()@

arr.map()(callbackFn,thisArg?)纯函数,用于对数组的每个元素执行转换操作,生成一个新数组

  • callbackFn(el,index?,arr?)=>any,定义每个元素的转换逻辑。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 map() 的原始数组。

    • 返回:

    • elany,返回新数组中的对应元素。

  • thisArg?any默认:undefined,指定 callbackFn 中的 this 值。

    • 注意:箭头函数忽略此参数(使用定义时的 this)。
  • 返回:

  • newArrarray,返回包含所有转换后元素的新数组。特性

    • 长度与原数组相同。
    • 元素顺序与原数组一致。
    • 不修改原数组(纯函数特性)。
    • 稀疏数组的空位会被保留(但跳过回调执行)。

核心特性

  1. 稀疏数组(空位处理)

    js
    const sparse = [1, , 3]; // 索引1为空位
    const mapped = sparse.map(x => {
      console.log(x); // 只输出1和3(跳过空位)
      return x * 2;
    });
    
    console.log(mapped); // [2, empty, 6](保留空位)
  2. 未定义返回值

    js
    [1, 2, 3].map(() => {});
    // [undefined, undefined, undefined]
  3. 非函数参数

    js
    // 抛出TypeError
    [1, 2, 3].map(null);

示例

  1. 基本转换(数值运算)

    js
    const numbers = [1, 2, 3];
    const doubled = numbers.map(n => n * 2);
    console.log(doubled); // [2, 4, 6]
  2. 使用索引参数

    js
    const letters = ['a', 'b', 'c'];
    const indexed = letters.map((char, i) => `${i}_${char}`);
    console.log(indexed); // ["0_a", "1_b", "2_c"]
  3. 转换对象数组

    js
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 30 }
    ];
    
    const names = users.map(user => user.name);
    console.log(names); // ["Alice", "Bob"]
  4. 使用 thisArg 绑定上下文

    js
    const multiplier = {
      factor: 10,
      multiply(x) {
        return x * this.factor;
      }
    };
    
    const nums = [1, 2, 3];
    const result = nums.map(function(x) {
      return this.multiply(x);
    }, multiplier);
    
    console.log(result); // [10, 20, 30]
filter()@

arr.filter()(callbackFn,thisArg?)纯函数,用于筛选数组元素,返回一个新数组,包含所有通过测试的元素

  • callbackFn(el,index?,arr?)=>boolean,回调函数,定义筛选条件,对每个元素执行一次。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 filter() 的原数组。

    • 返回:

    • isFilteredboolean,返回值:

      • true:保留该元素到新数组。

      • false:跳过该元素。

  • thisArg?any默认:undefined,指定 callbackFn 中的 this 值。

  • 返回:

  • filteredarray,返回新数组,包含所有通过测试的元素。行为规则

    • 若没有元素通过测试,返回空数组。
    • 稀疏数组的空位会被跳过(不会触发回调函数)。
    • 浅拷贝:新数组中的对象元素与原数组共享引用。

示例

  1. 基本筛选(数值过滤)

    js
    const numbers = [1, 2, 3, 4, 5];
    const evenNumbers = numbers.filter(num => num % 2 === 0);
    console.log(evenNumbers); // [2, 4]
  2. 对象数组筛选

    js
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 17 },
      { name: "Charlie", age: 30 },
    ];
    const adults = users.filter(user => user.age >= 18);
    console.log(adults); // [{name: "Alice", age: 25}, {name: "Charlie", age: 30}]
  3. 使用 index 参数

    js
    const letters = ["a", "b", "c", "d"];
    const filtered = letters.filter((letter, index) => index % 2 === 0);
    console.log(filtered); // ["a", "c"]
  4. 结合 thisArg(指定 this 上下文)

    js
    const threshold = 3;
    const nums = [1, 2, 3, 4];
    const result = nums.filter(function(num) {
      return num > this.value; // this 指向 { value: threshold }
    }, { value: threshold });
    console.log(result); // [4]

进阶扩展

  1. 过滤稀疏数组的空位

    js
    const sparseArr = [1, , 3, , 5]; // 空位在索引1和3
    const filtered = sparseArr.filter(() => true);
    console.log(filtered); // [1, 3, 5](空位被跳过)
  2. 回调函数未返回布尔值

    js
    const arr = [0, 1, "2", null];
    const result = arr.filter(el => el); // 隐性转换为布尔值
    console.log(result); // [1, "2"](0、null 被过滤)
  3. 避免副作用

    回调函数应专注于条件判断,避免修改原数组或外部变量。

    js
    // 不推荐:在 filter 中修改原数组
    const arr = [1, 2, 3];
    arr.filter((num, index, array) => {
      array.pop(); // 危险操作!会改变原数组长度
      return num > 1;
    });
  4. 浅拷贝陷阱

    修改新数组中的对象元素会影响原数组中的对应元素。

    js
    const original = [{ x: 1 }, { x: 2 }];
    const filtered = original.filter(obj => obj.x > 0);
    filtered[0].x = 100;
    console.log(original[0].x); // 100(共享引用)
reduce()@

arr.reduce()(callbackFn,initialValue?),用于将数组元素依次累积处理,最终合并为单个值。

  • callbackFn(accumulator,currValue,currIndex?,arr?)=>newAccumulator,定义累积逻辑,对每个元素执行一次。

    • accumulatorany,累积值,初始为 initialValue 或数组第一个元素。

    • currValueany,当前处理的元素。

    • currIndex?number,当前元素的索引。

    • arr?array,原数组。

    • 返回:

    • newAccumulatorany回调函数必须返回新的累积值,作为下一次调用的 accumulator

  • initialValue?any,累积初始值。默认行为

    • 若省略,accumulator 初始化为数组第一个元素,currentValue 从第二个元素开始。

    • 若提供,accumulator 初始为 initialValuecurrentValue 从第一个元素开始。

  • 返回:

  • finalAccumulatorany,返回最终累积值:最后一次调用 callbackFn 返回的 accumulator

示例

  1. 数字数组求和(有初始值)

    js
    const nums = [1, 2, 3];
    const sum = nums.reduce((acc, curr) => acc + curr, 0); // 0 + 1 + 2 + 3
    console.log(sum); // 6
  2. 数字数组求和(无初始值)

    js
    const nums = [1, 2, 3];
    const sum = nums.reduce((acc, curr) => acc + curr); // 1 + 2 + 3
    console.log(sum); // 6(acc 初始为 1,依次加 2、3)
  3. 处理对象数组

    js
    const items = [{x: 1}, {x: 2}, {x: 3}];
    const totalX = items.reduce((acc, item) => acc + item.x, 0);
    console.log(totalX); // 6
  4. 扁平化数组

    js
    const nested = [[1, 2], [3, 4], [5, 6]];
    const flat = nested.reduce((acc, curr) => acc.concat(curr), []);
    console.log(flat); // [1, 2, 3, 4, 5, 6]

进阶扩展

  1. 空数组报错

    js
    [].reduce((acc, curr) => acc + curr); // TypeError: Reduce of empty array with no initial value
  2. 稀疏数组跳过空位

    js
    const sparseArr = [1, , 3];
    const result = sparseArr.reduce((acc, curr) => acc + (curr || 0), 0);
    console.log(result); // 4(空位被视为 undefined,跳过处理)
  3. 单元素数组

    js
    const single = [10];
    const val = single.reduce((acc, curr) => acc * curr);
    console.log(val); // 10(无初始值,直接返回唯一元素)
some()@

arr.some()(callbackFn,thisArg?)纯函数,用于检测数组中是否存在至少一个元素满足指定条件,返回布尔值。

  • callbackFn(el,index?,arr?)=>boolean,定义检测条件,对每个元素执行一次。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 some() 的原数组。

    • 返回:

    • isSomeboolean,返回值:

      • true:元素通过检测,some() 立即终止遍历并返回 true

      • false:元素未通过检测,继续检测下一个元素。

  • thisArg?any默认:undefined,指定 callbackFn 中的 this 值。

  • 返回:

  • isAllPassedboolean,返回值:

    • true:至少有一个元素通过检测。
    • false:所有元素均未通过检测(若数组为空,默认返回 false)。

核心特性:类似 arr.every()

  1. 特殊规则

    • 空数组调用:直接返回 false(无元素满足条件)。

      js
      const isEmptyValid = [].some(() => true); 
      console.log(isEmptyValid); // false(无元素可检测)
    • 稀疏数组:空位会被跳过(不会触发回调函数)。

      js
      const sparseArr = [1, , 3]; // 空位在索引1
      const hasEven = sparseArr.some(num => num % 2 === 0);
      console.log(hasEven); // false(实际检测元素为1和3)
  2. 立即终止遍历

    js
    const arr = [2, 4, 6, 7, 8];
    let count = 0;
    const hasOdd = arr.some(num => {
      count++;
      return num % 2 !== 0;
    });
    console.log(hasOdd); // true(检测到7时终止)
    console.log(count);   // 4(仅执行到索引3)
  3. 对比 every()

    • every()
      • 所有元素满足条件,返回true
      • 空数组,返回true
    • some()
      • 至少一个元素满足条件,返回true
      • 空数组,返回false
  4. 回调函数需返回布尔值

    若返回非布尔值,会隐式转换为布尔值(如 0nullundefined 视为 false)。

    js
    const arr = [0, "", null];
    const hasTruthy = arr.some(el => el); // 隐性转换:非真即假
    console.log(hasTruthy); // false(所有元素均为假值)
  5. 避免修改原数组

    在回调中修改数组可能导致意外结果(如删除元素会跳过后续检测)。

    js
    const arr = [1, 2, 3];
    const result = arr.some((num, index, array) => {
      array.pop(); // 危险!遍历时修改数组长度
      return num > 2;
    });
    console.log(result); // false(仅检测前两个元素)

示例

  1. 基本用法(存在性检测)

    js
    const nums = [1, 2, 3, 4];
    const hasEven = nums.some(num => num % 2 === 0);
    console.log(hasEven); // true(存在偶数)
  2. 对象数组检测

    js
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 17 },
      { name: "Charlie", age: 30 },
    ];
    const hasAdult = users.some(user => user.age >= 18);
    console.log(hasAdult); // true(Alice 和 Charlie 满足)
  3. 使用 thisArg(绑定上下文)

    js
    const threshold = 3;
    const nums = [1, 2, 3, 4];
    const result = nums.some(function(num) {
      return num > this.value; // this 指向 { value: threshold }
    }, { value: threshold });
    console.log(result); // true(4 > 3)
every()@

arr.every()(callbackFn,thisArg?)纯函数,用于检测数组中的所有元素是否都满足指定条件,返回布尔值。

  • callbackFn(el,index?,arr?)=>boolean,定义检测条件,对每个元素执行一次。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 every() 的原数组。

    • 返回:

    • isEveryboolean,返回值:

      • true:元素通过检测。

      • false:元素未通过检测,every() 立即停止遍历并返回 false

  • thisArg?any默认:undefined,指定 callbackFn 中的 this 值。

  • 返回:

  • isAllPassedboolean,返回值:

    • true:所有元素均通过检测(若数组为空,默认返回 true)。
    • false:至少有一个元素未通过检测。

核心特性

  1. 特殊规则

    • 空数组调用:直接返回 true(无元素违反条件)。

      js
      const isEmptyValid = [].every(() => false); 
      console.log(isEmptyValid); // true(无元素需检测)
    • 稀疏数组:空位会被跳过(不会触发回调函数)。

      js
      const sparseArr = [1, , 3]; // 空位在索引1
      const allExist = sparseArr.every(num => num !== undefined);
      console.log(allExist); // true(空位未触发回调,实际检测元素为1和3)
  2. 立即终止遍历

    js
    const arr = [2, 4, 6, 7, 8];
    let count = 0;
    const isAllEven = arr.every(num => {
      count++;
      return num % 2 === 0;
    });
    console.log(isAllEven); // false(检测到7时终止)
    console.log(count);     // 4(仅执行到索引3)
  3. 对比 some()

    • every()
      • 所有元素满足条件,返回true
      • 空数组,返回true
    • some()
      • 至少一个元素满足条件,返回true
      • 空数组,返回false
  4. 回调函数需返回布尔值

    若返回非布尔值,会隐式转换为布尔值(如 0nullundefined 视为 false)。

    js
    const arr = [1, 2, 3];
    const allTruthy = arr.every(el => el); // 隐性转换:非0即真
    console.log(allTruthy); // true
  5. 避免修改原数组

    在回调中修改数组可能导致意外结果(如删除元素会跳过后续检测)。

    js
    const arr = [1, 2, 3];
    const result = arr.every((num, index, array) => {
      array.pop(); // 危险!遍历时修改数组长度
      return num > 0;
    });
    console.log(result); // true(仅检测前两个元素)

示例

  1. 基本用法(数值检测)

    js
    const nums = [10, 20, 30, 40];
    const allOver5 = nums.every(num => num > 5);
    console.log(allOver5); // true
  2. 对象数组检测

    js
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 17 },
      { name: "Charlie", age: 30 },
    ];
    const allAdults = users.every(user => user.age >= 18);
    console.log(allAdults); // false(Bob 未通过)
  3. 使用 thisArg(绑定上下文)

    js
    const threshold = 3;
    const nums = [1, 2, 3, 4];
    const result = nums.every(function(num) {
      return num <= this.value; // this 指向 { value: threshold }
    }, { value: threshold });
    console.log(result); // false(4 > 3)

扁平化方法

flat()@

arr.flat()(depth?)ES2019纯函数,用于将嵌套的多维数组“拉平”为一维或多维数组,返回一个新数组。

  • depth?number默认:1,控制拉平层级。行为规则

    • depth = 0:返回原数组的浅拷贝(不拉平)。

    • depth < 0:视为 0

    • depth = Infinity:完全拉平所有层级的嵌套数组。

  • 返回:

  • newArrarray,返回拉平后的新数组,原数组保持不变。

核心特性

  1. 空位处理

    稀疏数组中的空位会被移除,转为 undefined

    js
    const sparse = [1, , 3]; // 空位在索引1
    console.log(sparse.flat()); // [1, 3](空位被移除)
  2. 参数类型隐式转换

    非整数值会被自动向下取整

    js
    // 非整数 → 取整
    console.log([[[1]]].flat(2.5)); // [1](depth = 2)
    
    // 非数值 → 转换为整数(失败则视为0)
    console.log([[[1]]].flat("2"));   // [1](depth = 2)
    console.log([[[1]]].flat("abc")); // [[[1]]](depth = 0)
  3. 对比 flatMap()

    • flat():仅拉平数组。
    • flatMap():先映射再拉平一层。等价于:array.map(...).flat(1)
  4. 性能优化

    对深度嵌套的数组使用 depth = Infinity 可能导致性能问题,需谨慎处理。

示例

  1. 默认拉平一层

    js
    const arr = [1, [2, [3]]];
    console.log(arr.flat());    // [1, 2, [3]](仅拉平一层)
  2. 指定拉平层级

    js
    const nested = [1, [2, [3, [4]]]];
    console.log(nested.flat(2)); // [1, 2, 3, [4]](拉平两层)
    console.log(nested.flat(Infinity)); // [1, 2, 3, 4](完全拉平)
  3. 处理非数组元素:非数组元素保留

    js
    const mixed = [1, {x: 2}, "hello", [3, [4]]];
    console.log(mixed.flat()); // [1, {x: 2}, "hello", 3, [4]](非数组元素保留)

进阶扩展

  1. ****:

    js
  2. ****:

    js
  3. ****:

    js
flatMap()@

arr.flatMap()(callback,thisArg?)ES2019,将映射(map)和扁平化(flat)操作合并为一步

  • callback(el,index?,arr?),对数组每个元素执行的回调函数。

    • elany,当前处理的元素。

    • index?number,当前元素的索引。

    • arr?array,调用 flatMap() 的数组。

    • 返回:

    • resultarray|Iterator,必须返回一个数组或可迭代对象(如 Set、Map),非数组值会被自动包装为单元素数组。

  • thisArg?any默认:undefined,执行 callback 时的 this 值。

  • 返回:

  • newArrarray,返回包含所有映射并扁平化后的元素。特性

    • 总是返回新数组(不修改原数组)
    • 自动进行单层扁平化(相当于 .map().flat(1)
    • 稀疏数组的空位会被跳过(不执行回调)

核心特性

  1. 等价于 map().flat()

    js
    const arr = [1, 2, 3];
    
    // 传统方式
    const mapped = arr.map(x => [x, x * 2]); // [[1,2], [2,4], [3,6]]
    const flattened = mapped.flat(); // [1,2,2,4,3,6]
    
    // flatMap 方式
    const result = arr.flatMap(x => [x, x * 2]); // [1,2,2,4,3,6]
  2. 稀疏数组处理:跳过空位

    js
    [1, , 3].flatMap(x => [x * 2]); 
    // [2, 6](跳过空位)

示例

  1. 基本用法(映射+扁平化)

    js
    const arr = [1, 2, 3];
    const result = arr.flatMap(x => [x, x * 2]);
    console.log(result); // [1, 2, 2, 4, 3, 6]
  2. 使用索引参数

    js
    ["a", "b", "c"].flatMap((char, i) => [char + i]); 
    // ["a0", "b1", "c2"]
  3. 过滤元素(返回空数组)

    js
    const numbers = [1, 2, 3, 4];
    const evens = numbers.flatMap(x => x % 2 === 0 ? [x] : []);
    console.log(evens); // [2, 4](相当于 filter)
  4. 处理嵌套数组

    js
    const phrases = ["hello world", "goodbye moon"];
    const words = phrases.flatMap(phrase => phrase.split(' '));
    console.log(words); // ["hello", "world", "goodbye", "moon"]

进阶扩展

  1. 数据清洗与转换

    js
    const data = [
      { id: 1, tags: ["js", "web"] },
      { id: 2, tags: ["node", "backend"] }
    ];
    
    const allTags = data.flatMap(item => item.tags);
    // ["js", "web", "node", "backend"]
  2. 矩阵变换

    js
    const matrix = [
      [1, 2],
      [3, 4],
      [5, 6]
    ];
    
    const transposed = matrix.flatMap(
      (row, i) => row.map((_, j) => matrix[j][i])
    );
    // [[1, 3, 5], [2, 4, 6]]

迭代器方法

entries()@

arr.entries()(),用来返回一个新的数组迭代器对象,包含数组中每个索引的键值对

  • 返回:

  • iteratorIterator,返回一个新的 Array Iterator 对象,该对象遵循 迭代器协议,包含数组中每个索引的键值对。

核心特性

  1. 迭代项格式:每个迭代项是一个形如 [index, value] 的数组,其中:

    • index:当前元素的索引(从 0 开始)。
    • value:当前元素的值。
  2. 迭代器的一次性

    迭代器遍历完成后无法重置,需重新调用 entries() 生成新迭代器。

    js
    const iterator = arr.entries();
    console.log([...iterator]); // 第一次遍历完成
    console.log([...iterator]); // [](无剩余元素)
  3. 不可直接用于 forEach

    迭代器需通过 for...ofnext() 或转换为数组后使用。

  4. 对象引用保留

    若数组元素是对象,迭代器返回的 value 是原对象的引用(修改会影响原数组)。

  5. 处理稀疏数组

    空位(未被赋值的索引)对应的 valueundefined,但索引仍会被遍历,如 [index, undefined]

    js
    const sparseArr = [1, , 3]; // 索引1为空位
    const iterator = sparseArr.entries();
    
    console.log([...iterator]); 
    // [[0, 1], [1, undefined], [2, 3]](空位视为 undefined)

示例

  1. 基本用法(遍历数组)

    js
    const fruits = ["apple", "banana", "orange"];
    const iterator = fruits.entries();
    
    // 手动迭代
    console.log(iterator.next().value); // [0, "apple"]
    console.log(iterator.next().value); // [1, "banana"]
    console.log(iterator.next().value); // [2, "orange"]
    console.log(iterator.next().done);  // true(遍历完成)
    
    // 结合 for...of 循环
    for (const [index, value] of fruits.entries()) {
      console.log(`Index ${index}: ${value}`);
    }
    // 输出:
    // Index 0: apple
    // Index 1: banana
    // Index 2: orange

进阶扩展

  1. 转换迭代器为数组

    js
    const arr = ["a", "b"];
    const entriesArray = Array.from(arr.entries());
    console.log(entriesArray); // [[0, "a"], [1, "b"]]
keys()@

arr.keys()()ES2015,用来获取数组索引的迭代器

  • 返回:

  • iteratorIterator,返回一个新的 Array Iterator 对象,遵循 迭代器协议,包含数组中每个元素的索引

核心特性:类似 entries()

  1. 迭代项格式

    每个迭代项的 value 是数组的索引(从 0 开始),类型为 number

  2. 迭代器的一次性

    迭代器遍历完成后无法重置,需重新调用 keys() 生成新迭代器。

    js
    const iterator = arr.keys();
    console.log([...iterator]); // [0, 1](第一次遍历)
    console.log([...iterator]); // [](已遍历完毕)
  3. 不可直接用于 forEach

    迭代器需通过 for...ofnext() 或转换为数组后使用。

  4. 处理稀疏数组

    空位的索引仍会被遍历。

    js
    const sparseArr = [1, , 3]; // 索引1为空位
    const iterator = sparseArr.keys();
    
    console.log([...iterator]); // [0, 1, 2](空位的索引仍被包含)

示例

  1. 遍历数组索引

    js
    const fruits = ["apple", "banana", "orange"];
    const iterator = fruits.keys();
    
    // 手动调用 next() 遍历
    console.log(iterator.next().value); // 0
    console.log(iterator.next().value); // 1
    console.log(iterator.next().value); // 2
    console.log(iterator.next().done);  // true(遍历完成)
    
    // 结合 for...of 循环
    for (const index of fruits.keys()) {
      console.log(`Index: ${index}`);
    }
    // 输出:
    // Index: 0
    // Index: 1
    // Index: 2

进阶扩展

  1. 转换迭代器为数组

    js
    const arr = ["a", "b"];
    const keysArray = Array.from(arr.keys());
    console.log(keysArray); // [0, 1]
values()@

arr.values()()ES2015,用来获取数组元素值的迭代器

  • 返回:

  • iteratorIterator,返回一个新的 Array Iterator 对象,遵循 迭代器协议,包含数组中每个元素的值

核心特性:类似 entries() / keys()

  1. 迭代项格式

    每个迭代项的 value 是数组的元素值,类型与原数组元素一致。

  2. 迭代器的一次性

    迭代器遍历完成后无法重置,需重新调用 values() 生成新迭代器。

    js
    const iterator = arr.values();
    console.log([...iterator]); // ["a", "b"](第一次遍历)
    console.log([...iterator]); // [](已遍历完毕)
  3. 处理稀疏数组

    空位的值会被视为 undefined,但索引仍会被保留。

    js
    const sparseArr = [1, , 3]; // 索引1为空位
    const iterator = sparseArr.values();
    
    console.log([...iterator]); 
    // [1, undefined, 3](空位视为 `undefined`)
  4. 与默认迭代行为一致

    直接使用 for...of 遍历数组时,默认调用 values() 方法。

    js
    // 以下两种方式等价:
    for (const value of arr) { /* ... */ }
    for (const value of arr.values()) { /* ... */ }

示例

  1. 遍历数组元素值

    js
    const fruits = ["apple", "banana", "orange"];
    const iterator = fruits.values();
    
    // 手动调用 next() 遍历
    console.log(iterator.next().value); // "apple"
    console.log(iterator.next().value); // "banana"
    console.log(iterator.next().value); // "orange"
    console.log(iterator.next().done);  // true(遍历完成)
    
    // 结合 for...of 循环
    for (const value of fruits.values()) {
      console.log(`Value: ${value}`);
    }
    // 输出:
    // Value: apple
    // Value: banana
    // Value: orange

进阶扩展

  1. 转换迭代器为数组

    js
    const arr = ["a", "b"];
    const valuesArray = Array.from(arr.values());
    console.log(valuesArray); // ["a", "b"]