Array
[TOC]
索引
静态方法:
- Array.from():
(arrayLike,mapFn?,thisArg?)
,静态方法,用于将类数组对象或可迭代对象转换为真正的数组,并支持对元素进行映射处理。 - Arrary.of():
(el1, el2, ..., elN?)
,ES2015,静态方法,用于创建包含可变数量参数的新数组,解决传统Array()
构造函数在处理单个数值参数时的歧义问题。 - Array.isArray():
(value)
,静态方法,用来判断一个变量是否为数组的方法。
属性:
- array.length:
number
,获取或设置数组的长度,直接反映数组中元素的数量(或最大索引加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?)
,修改原数组,用于填充数组。从start
到end-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.length:number
,获取或设置数组的长度,直接反映数组中元素的数量(或最大索引加1)。
语法:
// 1. 获取数组长度
const len = array.length;
// 2. 设置数组长度
array.length = newLength;
核心行为:
获取长度:返回数组的最大索引加1,包括稀疏数组的空位。
jsconst sparseArr = [1, , 3]; // 稀疏数组(索引1为空位) console.log(sparseArr.length); // 3(最大索引2 + 1)
设置长度:
缩短数组(新长度 < 当前长度):超出新长度的元素会被删除,数组被截断。
jsconst arr = [1, 2, 3, 4, 5]; arr.length = 3; console.log(arr); // [1, 2, 3]
扩展数组(新长度 > 当前长度):新增的索引位置会被填充为 空位(非
undefined
,属于稀疏数组)。jsconst arr = [1, 2]; arr.length = 5; console.log(arr); // [1, 2, empty × 3]
参数处理规则:
数值转换:非数值类型会被转换为数值:
jsarr.length = "3"; // 转换为 3 arr.length = "3.5"; // 转换为 3.5 → 取整为3(部分环境可能抛出错误) arr.length = null; // 转换为 0 arr.length = true; // 转换为 1 arr.length = "abc"; // 转换为 NaN → 视为0(清空数组)
有效性检查:
合法范围:
0 ≤ newLength ≤ 2^32 - 1
(即4294967295
)。非法值处理:
负数:抛出
RangeError
。jsarr.length = -1; // RangeError: Invalid array length
非整数(如
3.5
):部分环境静默取整,部分抛出错误(建议避免)。jsarr.length = 3.5; // 可能设置为3或抛出错误(依环境而定)
超出
2^32 - 1
:抛出RangeError
。jsarr.length = 4294967296; // RangeError
注意事项:
稀疏数组的影响:扩展后的空位可能被部分数组方法(如
map
、forEach
)跳过,导致意外行为。jsconst arr = []; arr.length = 3; arr.forEach((v, i) => console.log(i)); // 无输出(空位被跳过)
快速清空数组:设置
length = 0
是清空数组的高效方法。jsconst arr = [1, 2, 3]; arr.length = 0; console.log(arr); // []
不可逆操作:缩短数组会永久删除超出新长度的元素,无法恢复。
静态方法
from()@
Array.from():(arrayLike,mapFn?,thisArg?)
,静态方法,用于将类数组对象或可迭代对象转换为真正的数组,并支持对元素进行映射处理。
arrayLike:
ArrayLike|Iterator
,待转换的类数组对象或可迭代对象。mapFn?:
(item,index)=>newItem
,对每个元素进行处理的回调函数。返回处理后的新元素,组成最终数组。thisArg?:
any
,执行 mapFn 时的 this 值。若 mapFn 是箭头函数,此参数无效。返回:
arr:
Array
,转换后的数组实例。
核心功能:
转换类数组对象:
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); // 转为数组后可调用数组方法
转换可迭代对象:
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']
使用映射函数:
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']
边界情况:
原始值处理:
jsArray.from(123); // [](数字不可迭代) Array.from(true); // [](布尔值不可迭代)
稀疏数组处理:
jsArray.from({ length: 3 }); // [undefined, undefined, undefined]
映射函数参数:
jsArray.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
,成为新数组的元素。返回:
arr:
array
,返回包含传入的所有参数作为元素的数组。
核心特性:
解决
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"](单元素数组)
参数处理规则:
空参数:创建空数组
jsArray.of(); // []
混合类型参数:保留所有类型
jsArray.of(1, "a", true, null, {x: 1}, [2]); // [1, "a", true, null, {x:1}, [2]]
特殊值处理:
jsArray.of(undefined); // [undefined] Array.of(null); // [null] Array.of(NaN); // [NaN]
对比相关方法:
方法 Array(3)
Array.of(3)
[3]
Array.from({length:3})
结果 [,,]
[3]
[3]
[undefined, undefined, undefined]
长度 3 1 1 3 稀疏性 是 否 否 否
isArray()@
Array.isArray():(value)
,静态方法,用来判断一个变量是否为数组的方法。
value:
any
,待检测的值,判断其是否为数组。返回:
isArray:
boolean
,返回是否为数组。
核心特性:
底层原理:
Array.isArray()
通过检查对象的内部[[Class]]
属性(或 ES6+ 的Symbol.toStringTag
)是否为"Array"
,从而实现精确判断。等价于:
jsfunction isArray(value) { return Object.prototype.toString.call(value) === '[object Array]'; }
跨执行环境检测::
若数组来自不同的全局环境(如 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
示例:
基本用法:
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():()
,用于创建数组的构造函数。行为根据参数类型和数量的不同而变化,生成密集数组或稀疏数组。
返回:
arr:
array
,数组实例,无论参数如何,始终返回一个数组对象。
语法:
// 构造函数形式
const arr1 = new Array(); // 空数组
const arr2 = new Array(length); // 指定长度的稀疏数组
const arr3 = new Array(elem1, elem2, ..., elemN); // 包含元素的数组
// 字面量等价形式(推荐)
const arr4 = []; // 空数组
const arr5 = [elem1, elem2]; // 包含元素的数组
核心特性:
参数类型:
无参数:创建空数组(
length
为0
)。jsconst arr = new Array(); // []
单个数值参数:创建长度为该数值的稀疏数组(空位填充)。
jsconst sparseArr = new Array(3); console.log(sparseArr); // [empty × 3] console.log(sparseArr.length); // 3
特殊值处理:
负数 → 抛出
RangeError
。jsnew Array(-1); // RangeError: Invalid array length
非整数(如
2.5
)→ 抛出RangeError
(部分环境可能静默截断,但应避免)。
多个参数或非数值参数:创建一个数组,元素为传入的参数。
jsnew Array(1, 2, 3); // [1, 2, 3] new Array("a", {x: 1}); // ["a", {x: 1}] new Array(true, null); // [true, null]
稀疏数组陷阱:
- 通过
new Array(length)
创建的数组元素为空位(非undefined
)。 - 访问空位返回
undefined
,但属性未被实际定义(in
操作符检测为false
)。
jsconst arr = new Array(3); console.log(arr[0]); // undefined console.log(0 in arr); // false(空位)
- 通过
进阶扩展:
单个数值参数的歧义问题:
js// 数值参数 → 创建稀疏数组 const arr1 = new Array(3); // [empty × 3] // 非数值参数 → 创建单元素数组 const arr2 = new Array("3"); // ["3"]
解决:使用 Array.of() 可以解决
new Array()
单个数值参数的歧义问题:jsArray.of(3); // [3](直接包含元素3) new Array(3); // [empty × 3](长度为3的稀疏数组)
避免稀疏数组:
问题:使用
new Array(length)
生成的稀疏数组可能导致意外行为(如forEach
、map
跳过空位)。jsconst 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]
优先使用字面量
[]
:- 更简洁:
[]
比new Array()
更高效且可读。 - 避免歧义:
new Array(3)
与[3]
结果完全不同。
- 更简洁:
修改原数组
push()
arr.push():(el1, el2, ..., elN?)
,修改原数组,用于在数组的末尾添加一个或多个元素,并返回新的数组长度。
el1, el2, ..., elN?:
any
,要添加到数组末尾的一个或多个元素。返回:
length:
number
,返回添加元素后数组的length
属性值。
核心特性:
直接修改原数组:
push()
会改变原数组,若需保留原数组,使用展开运算符或concat()
:jsconst newArr = [...oldArr, newElement]; // 创建新数组
引用类型元素:
添加对象或数组时,保存的是引用(修改引用对象会影响数组内容)。
jsconst obj = { x: 1 }; const arr = []; arr.push(obj); obj.x = 2; console.log(arr[0].x); // 2
性能优化:
- 添加多个元素时,一次性
push()
比多次调用更高效。 - 避免在循环中高频调用
push()
,可考虑批量处理。
- 添加多个元素时,一次性
示例:
添加单个或多个元素:
jsconst arr = [1, 2]; const newLength = arr.push(3, 4); console.log(arr); // [1, 2, 3, 4] console.log(newLength); // 4
添加数组或对象:
jsconst arr = ["a"]; arr.push([1, 2], { x: 1 }); console.log(arr); // ["a", [1, 2], { x: 1 }](数组作为单个元素添加)
空参数调用:
jsconst arr = [1, 2]; console.log(arr.push()); // 2(数组未修改,返回原长度)
pop()
arr.pop():()
,修改原数组,用于移除数组的最后一个元素,并返回该元素的值。
返回:
lastEl:
any|undefined
,返回值:- 如果数组 非空:返回数组的最后一个元素。
- 如果数组 为空:返回
undefined
。
核心特性:
直接修改原数组:
pop()
是原地操作,无返回值副本。需谨慎在需要保留原数组的场景中使用。性能优化:
- 尾部操作高效:
pop()
的时间复杂度为常数时间(O(1)),适合频繁删除末尾元素。 - 头部操作低效:若需频繁删除头部元素,建议使用
shift()
或考虑数据结构替换(如链表)。
- 尾部操作高效:
稀疏数组:
空位(未被赋值的索引)不会影响
pop()
的行为,仅移除最后一个有效元素。jsconst sparseArr = [1, , 3]; // 索引1为空位 sparseArr.pop(); // 移除3 → [1, empty]
示例:
移除并返回最后一个元素:
jsconst fruits = ["apple", "banana", "orange"]; const lastFruit = fruits.pop(); console.log(fruits); // ["apple", "banana"] console.log(lastFruit); // "orange"
进阶扩展:
循环清空数组:
通过循环
pop()
逐步清空数组。jswhile (arr.length > 0) { arr.pop(); }
shift()
arr.shift():()
,修改原数组,用于删除数组的第一个元素,并返回该元素,同时改变原数组的长度。
返回:
firstEl:
any|undefined
,返回被移除的数组的第一个元素;如果数组为空返回undefined
。
核心特性:
修改原数组:
直接删除数组的第一个元素,数组长度减
1
,后续元素向前移动一位。性能问题:
- 头部操作低效:
shift()
的时间复杂度为线性时间(O(n)),因为需要移动所有剩余元素。 - 大型数组慎用:频繁调用可能导致性能瓶颈,可考虑反向操作(先
reverse()
再pop()
)或使用链表。
- 头部操作低效:
稀疏数组空位处理:
若第一个元素是空位(未被赋值),
shift()
返回undefined
,但空位会被移除。jsconst arr = [, , 3]; console.log(arr.shift()); // undefined(移除第一个空位) console.log(arr); // [empty, 3](长度减1)
引用类型元素:
移除对象时返回的是原引用,修改会影响原对象。
jsconst obj = { x: 1 }; const arr = [obj]; const removedObj = arr.shift(); removedObj.x = 2; console.log(obj.x); // 2(原对象被修改)
示例:
移除并返回第一个元素:
jsconst 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
,要添加到数组开头的一个或多个元素。返回:
length:
number
,返回添加元素后数组的length
属性值。
核心特性:
直接修改原数组:
unshift()
会改变原数组,若需保留原数组,使用展开运算符或concat()
:jsconst newArr = [newElement, ...oldArr]; // 创建新数组
引用类型元素:
添加对象或数组时,保存的是引用(修改引用对象会影响数组内容)。
jsconst obj = { x: 1 }; const arr = []; arr.unshift(obj); obj.x = 2; console.log(arr[0].x); // 2
链式调用限制:
unshift()
返回新长度,无法直接链式调用数组方法。js[1, 2].unshift(3).map(x => x * 2); // 报错:length.map 不存在
性能问题:
- 头部操作低效:
shift()
的时间复杂度为线性时间(O(n)),因为需要移动所有剩余元素。 - 大型数组慎用:频繁调用可能导致性能瓶颈,可考虑反向操作(先
reverse()
再pop()
)或使用链表。
js// 频繁 unshift 大型数组可能导致性能问题(时间复杂度 O(n)) const largeArr = new Array(1e6).fill(0); largeArr.unshift(1); // 需要移动所有元素,效率低
- 头部操作低效:
示例:
数组头部添加元素:
jsconst arr = [3, 4]; const newLength = arr.unshift(1, 2); console.log(arr); // [1, 2, 3, 4] console.log(newLength); // 4
添加数组或对象:
jsconst arr = ["a"]; arr.unshift([1, 2], { x: 1 }); console.log(arr); // [[1, 2], { x: 1 }, "a"](数组作为单个元素添加)
空参数调用:
jsconst arr = [1, 2]; console.log(arr.unshift()); // 2(数组未修改,返回原长度)
splice()@
array.splice():(start,deleteCount?,item1?,item2?,...)
,修改原数组,可以删除、替换或添加元素。返回被删除的元素组成的数组。
start:
number
,开始修改的索引(从 0 开始)。start < 0
:从数组末尾倒数(例如,-2 表示倒数第二个元素)。start < -数组长度
:视为 0。start >= 数组长度
:从数组末尾开始操作(直接添加元素到末尾)。
deleteCount?:
number
,默认:0
,要删除的元素数量。deleteCount <= 0
:不删除元素(若未提供,则删除从 start 到末尾的所有元素)。deleteCount > 剩余元素数
:删除从 start 到末尾的所有元素。
item1?,item2?,...:
any
,从 start 位置开始插入的元素。如果不提供此参数,则仅删除元素。返回:
deleteArr:
Array
,返回被删除的元素组成的数组。
核心功能:
删除元素:
jsconst arr = [1, 2, 3, 4, 5]; arr.splice(1, 2); // 从索引1开始删除2个元素 console.log(arr); // [1, 4, 5] console.log(返回值); // [2, 3]
添加元素:
jsconst arr = [1, 2, 3]; arr.splice(1, 0, "a", "b"); // 从索引1开始添加元素,不删除 console.log(arr); // [1, "a", "b", 2, 3]
替换元素:
jsconst arr = [1, 2, 3]; arr.splice(1, 1, "x"); // 删除索引1的1个元素,插入"x" console.log(arr); // [1, "x", 3] console.log(返回值); // [2]
边界情况:
- 稀疏数组:空位会被跳过或处理为 undefined(取决于具体操作)。
sort()
arr.sort():(compareFn?)
,修改原数组,用于对数组的元素进行排序。
compareFn?:
(a,b)=>number
,定义排序顺序的比较逻辑。a:
any
,当前比较的第一个元素。b:
any
,当前比较的第二个元素。返回:
result:
number
,返回值:负数:
a
排在b
前面。零:
a
和b
顺序不变(ES2019+ 保证稳定排序)。正数:
b
排在a
前面。
返回:
sortedArr:
array
,返回排序后的原数组的引用。
核心特性:
默认排序(无参数)
将元素转换为字符串,按 Unicode 码点升序排列。
js[10, 2, 1].sort(); // [1, 10, 2](字符串比较) ["Banana", "apple"].sort(); // ["Banana", "apple"](Unicode 大小写敏感)
自定义比较函数:
数字升序:
js[10, 2, 1].sort((a, b) => a - b); // [1, 2, 10]
数字降序:
js[10, 2, 1].sort((a, b) => b - a); // [10, 2, 1]
对象属性排序:
jsconst users = [ { name: "Alice", age: 25 }, { name: "Bob", age: 30 }, { name: "Charlie", age: 20 }, ]; users.sort((a, b) => a.age - b.age); // 按 age 升序排列
字符串本地化排序:
使用
localeCompare()
按语言规则排序:js["ä", "a", "z"].sort((a, b) => a.localeCompare(b)); // ["a", "ä", "z"](德语环境)
稀疏数组:
空位(empty slots)被视为
undefined
,排序到数组末尾:jsconst sparse = [1, , 3]; sparse.sort(); // [1, 3, empty](空位被保留在末尾)
稳定性(ES2019+):
相同排序键的元素保持原有相对顺序:
jsconst arr = [ { name: "Alice", age: 25 }, { name: "Bob", age: 25 }, ]; arr.sort((a, b) => a.age - b.age); // Alice 和 Bob 的相对顺序不变(稳定排序)
示例:
多条件排序:
jsconst 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 排序 } });
逆序排序:
jsconst letters = ["a", "b", "c"]; letters.sort((a, b) => -1); // 所有元素逆序 → ["c", "b", "a"]
随机排序:
jsconst arr = [1, 2, 3, 4, 5]; arr.sort(() => Math.random() - 0.5); // 随机打乱数组(非均匀分布,慎用)
注意事项:
原地排序:
sort()
直接修改原数组,若需保留原数组,需先复制:jsconst sorted = [...array].sort();
比较函数必须返回数值:
返回非数值(如布尔值)可能导致意外结果:
js[1, 2, 3].sort(() => true); // 可能不会按预期排序(true → 1,false → 0)
性能与复杂度:
- 时间复杂度通常为 O(n log n)。
- 对大型数组(如超过10^5元素)需谨慎使用。
reverse()
arr.reverse():()
,修改原数组,用于将数组中的元素顺序颠倒的方法。
返回:
arr:
array
,返回反转后的原数组的引用。
核心特性:
元素交换规则:
第一个元素与最后一个元素交换,第二个与倒数第二个交换,依此类推。
稀疏数组的空位位置不变,仅调整已赋值元素的索引。
jsconst sparseArr = [1, , 3]; // 索引1为空位 sparseArr.reverse(); console.log(sparseArr); // [3, empty, 1](空位位置保留)
性能问题:
- 时间复杂度为 O(n),需遍历半数元素进行交换。
- 对超大型数组(如百万级元素)需谨慎使用,可能影响性能。
类数组对象支持:
可通过
call
或apply
将reverse()
应用于非数组对象(需包含length
属性)。jsconst nodeList = document.querySelectorAll("div"); Array.prototype.reverse.call(nodeList); // 反转元素集合
示例:
基本用法:
jsconst arr = [1, 2, 3]; arr.reverse(); console.log(arr); // [3, 2, 1](原数组被修改)
不修改原数组:
使用
slice().reverse()
可以保留原数组,仅获取反转副本jsconst arr = [1, 2, 3]; arr.slice().reverse(); console.log(arr); // [1, 2, 3](原数组被修改)
fill()
arr.fill():(value,start?,end?)
,修改原数组,用于填充数组。从 start
到 end-1
的元素被替换为 value
。
value:
any
,填充数组元素的值。start?:
number
,默认:0
,填充开始索引,会转换为整数,支持负数索引。end?:
number
,默认:array.length
,填充结束索引(不包含该位置),会转换为整数,支持负数索引。返回:
newArr:
array
,返回修改后的原数组。
核心特性:
直接修改原数组:
fill()
是原地操作,不会生成新数组。jsconst arr = [1, 2, 3]; const newArr = arr.fill(0); console.log(arr === newArr); // true
填充引用类型:
若
value
是对象,所有填充元素共享同一引用。jsconst arr = new Array(2).fill({}); arr[0].x = 1; console.log(arr[1].x); // 1(所有元素指向同一对象)
替代方案(生成新数组):
使用
Array.from()
或map()
避免修改原数组。jsconst newArr = Array.from({ length: 3 }, () => "a"); // ["a", "a", "a"]
示例:
基本填充:
jsconst 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]
填充稀疏数组:
jsconst sparse = new Array(3); // [empty × 3] sparse.fill(1); // 所有空位填充为1 → [1, 1, 1]
访问方法
concat()
array.concat():(value1?, value2?, ...)
,纯函数,用于合并数组或值,返回新数组。
value1?, value2?, ...:
any
,待合并的值,可以是数组、原始值、对象等。不同类型的处理规则不同:数组
:将数组的每个元素(仅展开一层)添加到新数组。非数组
:直接作为单个元素添加到新数组(包括null
、undefined
、Symbol
、类数组对象
)。
返回:
arr:
Array
,合并后的结果。参数为空执行浅拷贝。
核心行为:
合并数组:
jsconst arr1 = [1, 2]; const arr2 = [3, [4, 5]]; const merged = arr1.concat(arr2); // [1, 2, 3, [4, 5]](仅展开一层)
合并非数组值:
jsconst arr = [1]; const newArr = arr.concat("a", { x: 2 }, null); // [1, "a", {x: 2}, null]
空参数:
jsconst arr = [1, 2]; const copy = arr.concat(); // [1, 2](copy !== arr) 原数组的浅拷贝
稀疏数组
jsconst sparseArr = [1, , 3]; // 空位在索引1 const newArr = sparseArr.concat([4, 5]); // [1, empty, 3, 4, 5](保留空位)
类数组对象
jsconst arrayLike = { 0: "a", length: 1 }; const arr = [1].concat(arrayLike); // [1, {0: "a", length: 1}](不展开类数组对象)
注意事项:
性能优化:合并大型数组时,
concat()
可能比循环遍历更高效,但需注意内存占用。替代方案:使用扩展运算符实现类似效果(仅限可迭代对象):
jsconst merged = [...arr1, ...arr2, value];
slice()@
array.slice:(start?,end?)
,纯函数,用于提取数组的一部分,返回新数组。
start?:
number
,默认:0
,开始提取的索引(从 0 开始)。start < 0
:从数组末尾倒数(例如,-2 表示倒数第二个元素)。start >= 数组长度
:返回空数组。
end?:
number
,默认:数组长度
,结束提取的索引(不包含该位置)。end < 0
:从数组末尾倒数。end <= start
:返回空数组。
返回:
arr:
Array
,包含从 start 到 end(不含 end)的元素。
边界情况:
- 稀疏数组:空位保留(如
[1, ,3].slice(0,3)
→[1, empty, 3]
)。
示例:
基本使用:
jsconst 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
,默认:,
,字符串分割符。隐式转换为字符串。返回:
str:
string
,数组所有元素转换为字符串后,用separator
连接的结果。特殊情况:
- 空数组:返回空字符串
""
。 - 单个元素:直接返回该元素的字符串形式,无分隔符。
- 稀疏数组:空位视为空字符串,按位置插入分隔符。
- 空数组:返回空字符串
核心特性:
处理特殊值:
null
和undefined
:转换为空字符串。js[1, null, undefined, 4].join(); // "1,,,4"
对象:调用
toString()
方法。js[{}].join(); // "[object Object]"
稀疏数组:空位视为空字符串,按位置插入分隔符。
jsnew Array(3).join("a"); // "aa"(3个空位 → 两个分隔符) [1, , 3].join(); // "1,,3"(空位视为空字符串)
示例:
基本用法:
js[1, 2, 3].join(); // "1,2,3"(默认逗号分隔) ["a", "b", "c"].join("-"); // "a-b-c"
复杂类型处理:
jsconst mixed = [1, { name: "Alice" }, [2, 3], () => {}]; console.log(mixed.join(" | ")); // "1 | [object Object] | 2,3 | () => {}"
at()
arr.at():(index?)
,ES2022,用于通过索引访问数组元素,支持负数索引。
index?:
number
,默认:0
,要返回的数组元素的索引,会被转换为整数,支持负数索引。返回:
el:
any|undefined
,返回值:any
:若index
在有效范围内,返回对应位置的元素的值。undefined
:若index
超出数组范围(正数 ≥ 数组长度 或 负数绝对值 > 数组长度)。
核心特性:
对比
array[index]
:场景 array.at(index)
array[index]
支持负数索引 ✅(如 arr.at(-1)
)❌( arr[-1]
→undefined
)非数值参数处理 ✅ 隐式转换为整数 ✅ 隐式转换为字符串(可能意外匹配属性) 代码可读性 ✅ 更直观(语义明确) ❌ 需额外处理负数逻辑
示例:
基本用法:
jsconst 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)
结合可选链操作符使用:
避免中间结果为 undefined 导致的错误
js// 避免中间结果为 undefined 导致的错误 const safeValue = array.at?.(-1)?.property; // 可选链操作符结合使用
处理类数组对象:
jsconst arrayLike = { 0: "a", 1: "b", length: 2 }; console.log(Array.prototype.at.call(arrayLike, -1)); // "b"
搜索方法
indexOf()
arr.indexOf():(searchElement,fromIndex?)
,用于查找数组中指定元素的第一个匹配项的索引。若元素不存在,返回 -1
。
searchElement:
any
,要查找的目标元素。使用 严格相等(===
) 进行匹配(对象比较引用地址)。fromIndex?:
number
,默认:0
,开始搜索的索引,会转换为整数,支持负数索引。返回:
index:
number
,找到返回第一个匹配元素的索引;未找到返回-1
。
核心特性:
NaN 无法匹配:
替代方案:使用
includes()
或用findIndex(Number.isNaN)
处理jsconst 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 处理)
稀疏数组跳过空位:
jsconst sparseArr = [1, , 3]; // 空位在索引1 console.log(sparseArr.indexOf(undefined)); // -1(空位不会被显式处理)
示例:
基本查找:
jsconst 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(不同引用)
删除第一个匹配项:
jsconst 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?)
,于从数组末尾向前搜索指定元素,返回元素最后一次出现的索引位置。
- searchElement:
any
,要查找的目标元素。使用 严格相等(===
) 进行匹配(对象比较引用地址)。 - fromIndex?:
number
,默认:array.length-1
,从最后一个元素开始向前搜索,会转换为整数,支持负数索引。行为规则:- 正数:作为搜索的起始索引(从该位置向前搜索)。
- 负数:从数组末尾倒数的位置(如
-2
表示倒数第二个元素)。 - 超出范围:
fromIndex >= array.length
→ 搜索整个数组fromIndex < 0
→ 实际索引为max(0, array.length + fromIndex)
- 返回:
- index:
number
,找到的目标元素最后一次出现的索引;未找到返回-1
。
核心特性:类似 indexOf()
对比
indexOf()
:特性 lastIndexOf()
indexOf()
搜索方向 从后向前 从前向后 起始位置 默认 arr.length - 1
默认 0
查找逻辑 返回最后出现位置 返回首次出现位置 适用场景 查找最新日志、最后操作记录等 查找首次出现、存在性检查 NaN 无法匹配:
替代方案:使用
includes()
或用findIndex(Number.isNaN)
处理jsconst 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 处理)
稀疏数组跳过空位:
jsconst sparseArr = [1, , 3]; // 索引1为空位 console.log(sparseArr.lastIndexOf(undefined)); // -1(空位不会被检测)
边界情况:
jsconst 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开始向前)
严格相等比较:
js["1", 1].lastIndexOf(1); // 1(类型不同不匹配)
性能优化:
- 大型数组使用
lastIndexOf()
效率较低(O(n) 复杂度) - 如需高频查找,可考虑建立索引映射:
js// 创建值到最后一个索引的映射 const lastIndexMap = {}; arr.forEach((item, index) => { lastIndexMap[item] = index; // 始终记录最后出现的索引 });
- 大型数组使用
示例:
基本查找(从后向前):
jsconst 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?)
,用来判断数组是否包含某个元素,返回布尔值。
valueToFind:
any
,要搜索的元素,比较逻辑为 严格相等(===
)。fromIndex?:
number
,默认:0
,开始搜索的索引,会转换为整数,支持负索引。正数
:从索引fromIndex
开始向后搜索。负数
:从数组长度 + fromIndex
开始搜索(如fromIndex = -2
表示从倒数第二个位置开始)。超出范围
:若fromIndex ≥ 数组长度
,返回false
;若fromIndex < -数组长度
,从索引0
开始搜索。
返回:
isInclude:
boolean
,返回是否包含指定元素。
核心特性:
特殊值处理:
NaN
可被检测:与 indexOf 不同,indexOf 无法检测 NaNjs[NaN].includes(NaN); // true
undefined
与空位:稀疏数组的空位被视为 undefinedjs[1, , 3].includes(undefined); // true
对象检测:引用比较
jsconst obj = { x: 1 }; [obj].includes(obj); // true(同一引用) [{ x: 1 }].includes({ x: 1 }); // false(不同引用)
对比
indexOf()
:方法 检测 NaN 空位处理 返回值 语义清晰度 includes()
✅ 空位视为 undefined
布尔值 更直观(是/否) indexOf()
❌ 跳过空位 索引(无则 -1
)需额外判断
示例:
基本搜索:
jsconst arr = [1, 2, 3, 4]; console.log(arr.includes(3)); // true console.log(arr.includes(5)); // false
从指定位置搜索:
jsconst arr = ["a", "b", "c", "d"]; console.log(arr.includes("a", 1)); // false(从索引1开始) console.log(arr.includes("c", -2)); // true(等效于索引2)
处理稀疏数组:
jsconst sparse = [1, , 3]; console.log(sparse.includes(undefined)); // true
find()@
arr.find():(callbackFn,thisArg?)
,纯函数,用于查找数组中第一个满足条件的元素,返回该元素的值,若未找到则返回 undefined
。
callbackFn:
(el,index?,arr?)=>boolean
,定义查找条件,对每个元素执行一次,直到找到匹配项。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用find()
的原数组。返回:
result:
boolean
,返回值:true
:找到匹配元素,立即停止遍历并返回该元素。false
:继续查找下一个元素。
thisArg?:
any
,默认:undefined
,指定 callbackFn 中的 this 值。返回:
isFind:
any|undefined
,返回值:- 匹配的元素:第一个满足条件的元素值。
- 未找到:
undefined
。
核心特性:
特殊规则:
稀疏数组:空位会被跳过(不会触发回调)。
jsconst sparseArr = [1, , 3]; // 空位在索引1 const found = sparseArr.find(num => num === undefined); console.log(found); // undefined(空位未触发回调,实际检测元素为1和3)
中途终止:一旦找到匹配项,立即停止遍历。
严格匹配逻辑:
条件判断需明确,避免因隐式转换导致意外结果。
js// 隐性布尔转换示例 [0, 1, 2].find(num => num); // 1(0 视为 false,1 视为 true)
示例:
查找基本类型元素
jsconst nums = [5, 12, 8, 130, 44]; const found = nums.find(num => num > 10); console.log(found); // 12(第一个大于10的元素)
查找对象数组元素
jsconst 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 }
使用
thisArg
绑定上下文jsclass 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
,定义查找条件,对每个元素执行一次,直到找到匹配项。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用findIndex()
的原数组。返回:
result:
boolean
,返回值:true
:找到匹配元素,立即停止遍历并返回当前索引。false
:继续查找下一个元素。
thisArg?:
any
,默认:undefined
,指定 callbackFn 中的 this 值。返回:
isFind:
any|undefined
,返回值:- 匹配的索引:第一个满足条件的元素索引(从
0
开始)。 - 未找到:
-1
。
- 匹配的索引:第一个满足条件的元素索引(从
核心特性:
特殊规则:
稀疏数组:空位会被跳过(不会触发回调)。
jsconst sparseArr = [1, , 3]; // 空位在索引1 const index = sparseArr.findIndex(num => num === undefined); console.log(index); // -1(空位未触发回调,实际检测元素为1和3)
中途终止:一旦找到匹配项,立即停止遍历。
严格条件判断:
回调函数需明确返回布尔值,避免隐式转换导致误判。
js[0, 1, 2].findIndex(num => num); // 1(0视为false,1视为true)
示例:
查找基本类型元素
jsconst nums = [5, 12, 8, 130, 44]; const index = nums.findIndex(num => num > 10); console.log(index); // 1(第一个大于10的元素是12,索引为1)
未找到匹配元素
jsconst emptyResult = [1, 2, 3].findIndex(num => num > 5); console.log(emptyResult); // -1
查找对象数组元素
jsconst 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的索引)
使用
thisArg
绑定上下文jsclass 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的索引)
箭头函数无法绑定
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?)
,对数组中的每个元素执行的操作。el:
any
,当前处理的元素值。index?:
number
,当前元素的索引。arr?:
array
,调用forEach()
的原数组。
thisArg?:
any
,默认:undefined
,指定回调函数中的 this 值。- 注意:若使用箭头函数,此参数无效(箭头函数无自身
this
)。
- 注意:若使用箭头函数,此参数无效(箭头函数无自身
返回:
result:
undefined
,forEach()
始终返回undefined
,仅用于遍历操作,不生成新数组。
核心特性:
无法中断遍历:
即使回调函数中使用
return
或throw
,遍历仍会继续。替代方案:使用
for
循环或some()
/every()
提前终止。js// return 无法终止遍历 [1, 2, 3].forEach(num => { if (num === 2) return; console.log(num); // 1, 3(仍会输出3) });
异步操作问题:
forEach()
不会等待异步操作完成,可能导致意外结果。替代方案:使用
for...of
结合await
。js// 异步示例(不推荐) [1, 2, 3].forEach(async num => { await new Promise(resolve => setTimeout(resolve, 100)); console.log(num); // 可能乱序输出 });
示例:
遍历数组元素:
jsconst nums = [1, 2, 3]; nums.forEach((num, index) => { console.log(`索引 ${index}: 值 ${num}`); }); // 输出: // 索引 0: 值 1 // 索引 1: 值 2 // 索引 2: 值 3
修改原数组:
jsconst arr = [1, 2, 3]; arr.forEach((num, index, array) => { array[index] = num * 2; }); console.log(arr); // [2, 4, 6]
使用
thisArg
绑定上下文:jsclass 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
,定义每个元素的转换逻辑。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用map()
的原始数组。返回:
el:
any
,返回新数组中的对应元素。
thisArg?:
any
,默认:undefined
,指定 callbackFn 中的 this 值。- 注意:箭头函数忽略此参数(使用定义时的
this
)。
- 注意:箭头函数忽略此参数(使用定义时的
返回:
newArr:
array
,返回包含所有转换后元素的新数组。特性:- 长度与原数组相同。
- 元素顺序与原数组一致。
- 不修改原数组(纯函数特性)。
- 稀疏数组的空位会被保留(但跳过回调执行)。
核心特性:
稀疏数组(空位处理):
jsconst sparse = [1, , 3]; // 索引1为空位 const mapped = sparse.map(x => { console.log(x); // 只输出1和3(跳过空位) return x * 2; }); console.log(mapped); // [2, empty, 6](保留空位)
未定义返回值:
js[1, 2, 3].map(() => {}); // [undefined, undefined, undefined]
非函数参数:
js// 抛出TypeError [1, 2, 3].map(null);
示例:
基本转换(数值运算):
jsconst numbers = [1, 2, 3]; const doubled = numbers.map(n => n * 2); console.log(doubled); // [2, 4, 6]
使用索引参数:
jsconst letters = ['a', 'b', 'c']; const indexed = letters.map((char, i) => `${i}_${char}`); console.log(indexed); // ["0_a", "1_b", "2_c"]
转换对象数组:
jsconst users = [ { name: "Alice", age: 25 }, { name: "Bob", age: 30 } ]; const names = users.map(user => user.name); console.log(names); // ["Alice", "Bob"]
使用
thisArg
绑定上下文:jsconst 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
,回调函数,定义筛选条件,对每个元素执行一次。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用filter()
的原数组。返回:
isFiltered:
boolean
,返回值:true
:保留该元素到新数组。false
:跳过该元素。
thisArg?:
any
,默认:undefined
,指定 callbackFn 中的 this 值。返回:
filtered:
array
,返回新数组,包含所有通过测试的元素。行为规则:- 若没有元素通过测试,返回空数组。
- 稀疏数组的空位会被跳过(不会触发回调函数)。
- 浅拷贝:新数组中的对象元素与原数组共享引用。
示例:
基本筛选(数值过滤):
jsconst numbers = [1, 2, 3, 4, 5]; const evenNumbers = numbers.filter(num => num % 2 === 0); console.log(evenNumbers); // [2, 4]
对象数组筛选:
jsconst 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}]
使用
index
参数:jsconst letters = ["a", "b", "c", "d"]; const filtered = letters.filter((letter, index) => index % 2 === 0); console.log(filtered); // ["a", "c"]
结合
thisArg
(指定this
上下文):jsconst 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]
进阶扩展:
过滤稀疏数组的空位:
jsconst sparseArr = [1, , 3, , 5]; // 空位在索引1和3 const filtered = sparseArr.filter(() => true); console.log(filtered); // [1, 3, 5](空位被跳过)
回调函数未返回布尔值:
jsconst arr = [0, 1, "2", null]; const result = arr.filter(el => el); // 隐性转换为布尔值 console.log(result); // [1, "2"](0、null 被过滤)
避免副作用:
回调函数应专注于条件判断,避免修改原数组或外部变量。
js// 不推荐:在 filter 中修改原数组 const arr = [1, 2, 3]; arr.filter((num, index, array) => { array.pop(); // 危险操作!会改变原数组长度 return num > 1; });
浅拷贝陷阱:
修改新数组中的对象元素会影响原数组中的对应元素。
jsconst 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
,定义累积逻辑,对每个元素执行一次。accumulator:
any
,累积值,初始为initialValue
或数组第一个元素。currValue:
any
,当前处理的元素。currIndex?:
number
,当前元素的索引。arr?:
array
,原数组。返回:
newAccumulator:
any
,回调函数必须返回新的累积值,作为下一次调用的accumulator
。
initialValue?:
any
,累积初始值。默认行为:若省略,
accumulator
初始化为数组第一个元素,currentValue
从第二个元素开始。若提供,
accumulator
初始为initialValue
,currentValue
从第一个元素开始。
返回:
finalAccumulator:
any
,返回最终累积值:最后一次调用callbackFn
返回的accumulator
。
示例:
数字数组求和(有初始值):
jsconst nums = [1, 2, 3]; const sum = nums.reduce((acc, curr) => acc + curr, 0); // 0 + 1 + 2 + 3 console.log(sum); // 6
数字数组求和(无初始值):
jsconst nums = [1, 2, 3]; const sum = nums.reduce((acc, curr) => acc + curr); // 1 + 2 + 3 console.log(sum); // 6(acc 初始为 1,依次加 2、3)
处理对象数组:
jsconst items = [{x: 1}, {x: 2}, {x: 3}]; const totalX = items.reduce((acc, item) => acc + item.x, 0); console.log(totalX); // 6
扁平化数组
jsconst 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]
进阶扩展:
空数组报错:
js[].reduce((acc, curr) => acc + curr); // TypeError: Reduce of empty array with no initial value
稀疏数组跳过空位:
jsconst sparseArr = [1, , 3]; const result = sparseArr.reduce((acc, curr) => acc + (curr || 0), 0); console.log(result); // 4(空位被视为 undefined,跳过处理)
单元素数组:
jsconst single = [10]; const val = single.reduce((acc, curr) => acc * curr); console.log(val); // 10(无初始值,直接返回唯一元素)
some()@
arr.some():(callbackFn,thisArg?)
,纯函数,用于检测数组中是否存在至少一个元素满足指定条件,返回布尔值。
callbackFn:
(el,index?,arr?)=>boolean
,定义检测条件,对每个元素执行一次。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用some()
的原数组。返回:
isSome:
boolean
,返回值:true
:元素通过检测,some()
立即终止遍历并返回true
。false
:元素未通过检测,继续检测下一个元素。
thisArg?:
any
,默认:undefined
,指定 callbackFn 中的 this 值。返回:
isAllPassed:
boolean
,返回值:true
:至少有一个元素通过检测。false
:所有元素均未通过检测(若数组为空,默认返回false
)。
核心特性:类似 arr.every()
特殊规则:
空数组调用:直接返回
false
(无元素满足条件)。jsconst isEmptyValid = [].some(() => true); console.log(isEmptyValid); // false(无元素可检测)
稀疏数组:空位会被跳过(不会触发回调函数)。
jsconst sparseArr = [1, , 3]; // 空位在索引1 const hasEven = sparseArr.some(num => num % 2 === 0); console.log(hasEven); // false(实际检测元素为1和3)
立即终止遍历:
jsconst 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)
对比
every()
:every()
:- 所有元素满足条件,返回true
- 空数组,返回true
some()
:- 至少一个元素满足条件,返回true
- 空数组,返回false
回调函数需返回布尔值:
若返回非布尔值,会隐式转换为布尔值(如
0
、null
、undefined
视为false
)。jsconst arr = [0, "", null]; const hasTruthy = arr.some(el => el); // 隐性转换:非真即假 console.log(hasTruthy); // false(所有元素均为假值)
避免修改原数组:
在回调中修改数组可能导致意外结果(如删除元素会跳过后续检测)。
jsconst arr = [1, 2, 3]; const result = arr.some((num, index, array) => { array.pop(); // 危险!遍历时修改数组长度 return num > 2; }); console.log(result); // false(仅检测前两个元素)
示例:
基本用法(存在性检测):
jsconst nums = [1, 2, 3, 4]; const hasEven = nums.some(num => num % 2 === 0); console.log(hasEven); // true(存在偶数)
对象数组检测:
jsconst 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 满足)
使用
thisArg
(绑定上下文)jsconst 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
,定义检测条件,对每个元素执行一次。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用every()
的原数组。返回:
isEvery:
boolean
,返回值:true
:元素通过检测。false
:元素未通过检测,every()
立即停止遍历并返回false
。
thisArg?:
any
,默认:undefined
,指定 callbackFn 中的 this 值。返回:
isAllPassed:
boolean
,返回值:true
:所有元素均通过检测(若数组为空,默认返回true
)。false
:至少有一个元素未通过检测。
核心特性:
特殊规则:
空数组调用:直接返回
true
(无元素违反条件)。jsconst isEmptyValid = [].every(() => false); console.log(isEmptyValid); // true(无元素需检测)
稀疏数组:空位会被跳过(不会触发回调函数)。
jsconst sparseArr = [1, , 3]; // 空位在索引1 const allExist = sparseArr.every(num => num !== undefined); console.log(allExist); // true(空位未触发回调,实际检测元素为1和3)
立即终止遍历:
jsconst 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)
对比
some()
:every()
:- 所有元素满足条件,返回true
- 空数组,返回true
some()
:- 至少一个元素满足条件,返回true
- 空数组,返回false
回调函数需返回布尔值:
若返回非布尔值,会隐式转换为布尔值(如
0
、null
、undefined
视为false
)。jsconst arr = [1, 2, 3]; const allTruthy = arr.every(el => el); // 隐性转换:非0即真 console.log(allTruthy); // true
避免修改原数组:
在回调中修改数组可能导致意外结果(如删除元素会跳过后续检测)。
jsconst arr = [1, 2, 3]; const result = arr.every((num, index, array) => { array.pop(); // 危险!遍历时修改数组长度 return num > 0; }); console.log(result); // true(仅检测前两个元素)
示例:
基本用法(数值检测):
jsconst nums = [10, 20, 30, 40]; const allOver5 = nums.every(num => num > 5); console.log(allOver5); // true
对象数组检测:
jsconst 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 未通过)
使用 thisArg(绑定上下文):
jsconst 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
:完全拉平所有层级的嵌套数组。
返回:
newArr:
array
,返回拉平后的新数组,原数组保持不变。
核心特性:
空位处理:
稀疏数组中的空位会被移除,转为
undefined
。jsconst sparse = [1, , 3]; // 空位在索引1 console.log(sparse.flat()); // [1, 3](空位被移除)
参数类型隐式转换:
非整数值会被自动向下取整
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)
对比
flatMap()
:flat()
:仅拉平数组。flatMap()
:先映射再拉平一层。等价于:array.map(...).flat(1)
。
性能优化:
对深度嵌套的数组使用
depth = Infinity
可能导致性能问题,需谨慎处理。
示例:
默认拉平一层:
jsconst arr = [1, [2, [3]]]; console.log(arr.flat()); // [1, 2, [3]](仅拉平一层)
指定拉平层级:
jsconst nested = [1, [2, [3, [4]]]]; console.log(nested.flat(2)); // [1, 2, 3, [4]](拉平两层) console.log(nested.flat(Infinity)); // [1, 2, 3, 4](完全拉平)
处理非数组元素:非数组元素保留
jsconst mixed = [1, {x: 2}, "hello", [3, [4]]]; console.log(mixed.flat()); // [1, {x: 2}, "hello", 3, [4]](非数组元素保留)
进阶扩展:
****:
js****:
js****:
js
flatMap()@
arr.flatMap():(callback,thisArg?)
,ES2019,将映射(map)和扁平化(flat)操作合并为一步。
callback:
(el,index?,arr?)
,对数组每个元素执行的回调函数。el:
any
,当前处理的元素。index?:
number
,当前元素的索引。arr?:
array
,调用flatMap()
的数组。返回:
result:
array|Iterator
,必须返回一个数组或可迭代对象(如 Set、Map),非数组值会被自动包装为单元素数组。
thisArg?:
any
,默认:undefined
,执行 callback 时的 this 值。返回:
newArr:
array
,返回包含所有映射并扁平化后的元素。特性:- 总是返回新数组(不修改原数组)
- 自动进行单层扁平化(相当于
.map().flat(1)
) - 稀疏数组的空位会被跳过(不执行回调)
核心特性:
等价于
map().flat()
:jsconst 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]
稀疏数组处理:跳过空位
js[1, , 3].flatMap(x => [x * 2]); // [2, 6](跳过空位)
示例:
基本用法(映射+扁平化):
jsconst arr = [1, 2, 3]; const result = arr.flatMap(x => [x, x * 2]); console.log(result); // [1, 2, 2, 4, 3, 6]
使用索引参数:
js["a", "b", "c"].flatMap((char, i) => [char + i]); // ["a0", "b1", "c2"]
过滤元素(返回空数组):
jsconst numbers = [1, 2, 3, 4]; const evens = numbers.flatMap(x => x % 2 === 0 ? [x] : []); console.log(evens); // [2, 4](相当于 filter)
处理嵌套数组:
jsconst phrases = ["hello world", "goodbye moon"]; const words = phrases.flatMap(phrase => phrase.split(' ')); console.log(words); // ["hello", "world", "goodbye", "moon"]
进阶扩展:
数据清洗与转换:
jsconst data = [ { id: 1, tags: ["js", "web"] }, { id: 2, tags: ["node", "backend"] } ]; const allTags = data.flatMap(item => item.tags); // ["js", "web", "node", "backend"]
矩阵变换:
jsconst 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():()
,用来返回一个新的数组迭代器对象,包含数组中每个索引的键值对。
返回:
iterator:
Iterator
,返回一个新的 Array Iterator 对象,该对象遵循 迭代器协议,包含数组中每个索引的键值对。
核心特性:
迭代项格式:每个迭代项是一个形如
[index, value]
的数组,其中:index
:当前元素的索引(从0
开始)。value
:当前元素的值。
迭代器的一次性:
迭代器遍历完成后无法重置,需重新调用
entries()
生成新迭代器。jsconst iterator = arr.entries(); console.log([...iterator]); // 第一次遍历完成 console.log([...iterator]); // [](无剩余元素)
不可直接用于
forEach
:迭代器需通过
for...of
、next()
或转换为数组后使用。对象引用保留:
若数组元素是对象,迭代器返回的
value
是原对象的引用(修改会影响原数组)。处理稀疏数组:
空位(未被赋值的索引)对应的
value
为undefined
,但索引仍会被遍历,如[index, undefined]
。jsconst sparseArr = [1, , 3]; // 索引1为空位 const iterator = sparseArr.entries(); console.log([...iterator]); // [[0, 1], [1, undefined], [2, 3]](空位视为 undefined)
示例:
基本用法(遍历数组):
jsconst 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
进阶扩展:
转换迭代器为数组:
jsconst arr = ["a", "b"]; const entriesArray = Array.from(arr.entries()); console.log(entriesArray); // [[0, "a"], [1, "b"]]
keys()@
arr.keys():()
,ES2015,用来获取数组索引的迭代器。
返回:
iterator:
Iterator
,返回一个新的 Array Iterator 对象,遵循 迭代器协议,包含数组中每个元素的索引。
核心特性:类似 entries()
迭代项格式:
每个迭代项的
value
是数组的索引(从0
开始),类型为number
。迭代器的一次性:
迭代器遍历完成后无法重置,需重新调用
keys()
生成新迭代器。jsconst iterator = arr.keys(); console.log([...iterator]); // [0, 1](第一次遍历) console.log([...iterator]); // [](已遍历完毕)
不可直接用于
forEach
:迭代器需通过
for...of
、next()
或转换为数组后使用。处理稀疏数组:
空位的索引仍会被遍历。
jsconst sparseArr = [1, , 3]; // 索引1为空位 const iterator = sparseArr.keys(); console.log([...iterator]); // [0, 1, 2](空位的索引仍被包含)
示例:
遍历数组索引:
jsconst 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
进阶扩展:
转换迭代器为数组:
jsconst arr = ["a", "b"]; const keysArray = Array.from(arr.keys()); console.log(keysArray); // [0, 1]
values()@
arr.values():()
,ES2015,用来获取数组元素值的迭代器。
返回:
iterator:
Iterator
,返回一个新的 Array Iterator 对象,遵循 迭代器协议,包含数组中每个元素的值。
迭代项格式:
每个迭代项的
value
是数组的元素值,类型与原数组元素一致。迭代器的一次性:
迭代器遍历完成后无法重置,需重新调用
values()
生成新迭代器。jsconst iterator = arr.values(); console.log([...iterator]); // ["a", "b"](第一次遍历) console.log([...iterator]); // [](已遍历完毕)
处理稀疏数组:
空位的值会被视为
undefined
,但索引仍会被保留。jsconst sparseArr = [1, , 3]; // 索引1为空位 const iterator = sparseArr.values(); console.log([...iterator]); // [1, undefined, 3](空位视为 `undefined`)
与默认迭代行为一致:
直接使用
for...of
遍历数组时,默认调用values()
方法。js// 以下两种方式等价: for (const value of arr) { /* ... */ } for (const value of arr.values()) { /* ... */ }
示例:
遍历数组元素值:
jsconst 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
进阶扩展:
转换迭代器为数组:
jsconst arr = ["a", "b"]; const valuesArray = Array.from(arr.values()); console.log(valuesArray); // ["a", "b"]