在 JavaScript 编程中,数组是使用频率极高的数据结构。而操作数组的方法众多,其中一个关键的区分点在于,有些方法会修改原数组,有些则返回新数组而保持原数组不变。清晰掌握这两类方法,能让我们在编写代码时更加得心应手,避免因方法使用不当导致的意外错误。
一、修改原数组的方法
(一)push ()
push()方法用于在数组的末尾添加一个或多个元素。这一操作不仅会改变原数组的长度,还会直接改变其内容。它的返回值是新数组的长度。例如:
javascript
const arr = [1, 2, 3];
const newLength = arr.push(4);
console.log(arr);
console.log(newLength);
在上述代码中,arr原本是[1, 2, 3],执行arr.push(4)后,arr变为[1, 2, 3, 4],push()方法返回新数组的长度4。在实际应用中,当我们需要动态地向数组末尾添加元素,比如在一个购物车商品列表中添加新商品时,就可以使用push()方法。
(二)pop ()
pop()方法的作用是删除数组的最后一个元素。与push()相反,它会使原数组的长度减 1,并改变其内容。该方法的返回值是被删除的元素。示例如下:
javascript
const arr = [1, 2, 3];
const removedElement = arr.pop();
console.log(arr);
console.log(removedElement);
这里,arr初始为[1, 2, 3],执行arr.pop()后,arr变为[1, 2],返回值是被删除的元素3。在处理栈数据结构时,pop()方法就经常被用于从栈顶移除元素。
(三)splice ()
splice()方法功能较为强大,可以用于删除、插入或替换数组中的元素。它会直接修改原数组,并返回一个包含被删除元素的新数组,如果没有删除元素则返回空数组。其语法为array.splice(start, deleteCount, item1, item2, ...),其中start是起始索引,deleteCount是要删除的元素个数,后面的参数item1, item2, ...是要插入的新元素。例如:
javascript
const arr = [1, 2, 3, 4, 5];
const removedElements = arr.splice(2, 2, 6, 7);
console.log(arr);
console.log(removedElements);
在这段代码中,arr初始为[1, 2, 3, 4, 5],执行splice(2, 2, 6, 7)后,从索引2处开始删除2个元素(即3和4),并在该位置插入6和7,此时arr变为[1, 2, 6, 7, 5],返回值removedElements为被删除的元素[3, 4]。在对有序列表进行动态修改,如在播放列表中插入或删除歌曲时,splice()方法就非常实用。
(四)sort ()
sort()方法用于对数组的元素进行排序。默认情况下,它按照字符编码的顺序进行排序。这意味着如果数组中是数字,可能不会得到我们期望的数值大小排序结果。要实现数值大小排序,需要传入一个比较函数。无论哪种情况,sort()方法都会改变原数组中元素的顺序。例如:
javascript
const arr = [3, 1, 2];
arr.sort((a, b) => a - b);
console.log(arr);
上述代码中,arr初始为[3, 1, 2],通过传入比较函数(a, b) => a - b,sort()方法将数组按升序排列,arr变为[1, 2, 3]。在对成绩列表、价格列表等需要排序的数据进行处理时,sort()方法必不可少。
(五)reverse ()
reverse()方法用于颠倒数组中元素的顺序,直接修改原数组。例如:
javascript
const arr = [1, 2, 3];
arr.reverse();
console.log(arr);
这里,arr原本是[1, 2, 3],执行reverse()后,变为[3, 2, 1]。在处理需要倒序展示的数据,如历史记录列表时,reverse()方法能快速实现需求。
(六)shift ()
shift() 方法用于删除数组的第一个元素,会改变原数组的长度和内容,返回被删除的元素。例如:
javascript
const arr = [1, 2, 3];
const shiftedElement = arr.shift();
console.log(arr); // 输出 [2, 3]
console.log(shiftedElement); // 输出 1
(七)unshift ()
unshift()方法用于在数组的开头添加一个或多个元素,会改变原数组的长度和内容,返回新数组的长度。例如:
javascript
const arr = [1, 2, 3];
arr.unshift(0);
console.log(arr); // 输出 [0, 1, 2, 3]
(八)fill ()
fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。如果不指定起始索引和终止索引,将填充整个数组。此方法会改变原数组。例如:
javascript
const arr = [1, 2, 3, 4, 5];
arr.fill(0, 2, 4);
console.log(arr);
上述代码中,arr 初始为 [1, 2, 3, 4, 5],执行 fill(0, 2, 4) 后,从索引 2(包括)到索引 4(不包括)的元素被替换为 0,数组变为 [1, 2, 0, 0, 5]。在需要初始化数组部分元素为特定值时,fill() 方法很有用。
二、返回新数组的方法
(一)map ()
map()方法会创建一个新数组,新数组的元素是通过对原数组中的每个元素调用一个提供的函数而得到的结果。原数组在这个过程中不会被修改。例如:
javascript
const arr = [1, 2, 3];
const newArr = arr.map(item => item * 2);
console.log(newArr);
console.log(arr);
在这段代码中,arr为[1, 2, 3],通过map()方法对每个元素乘以2,得到新数组newArr为[2, 4, 6],而原数组arr保持不变。当我们需要对数组中的所有元素进行统一的转换操作,如将一个包含商品价格的数组中的价格都打八折时,map()方法就派上用场了。
(二)filter ()
filter()方法创建一个新数组,其中包含原数组中满足提供的过滤函数条件的所有元素。原数组在这个过程中不会发生改变。例如:
javascript
const arr = [1, 2, 3, 4, 5];
const newArr = arr.filter(item => item > 3);
console.log(newArr);
console.log(arr);
这里,arr初始为[1, 2, 3, 4, 5],通过filter()方法筛选出大于3的元素,得到新数组newArr为[4, 5],原数组arr依旧是[1, 2, 3, 4, 5]。在从一个用户列表中筛选出特定年龄段的用户,或者从一个文件列表中筛选出特定类型的文件时,filter()方法就显得尤为重要。
(三)slice ()
slice()方法用于提取原数组的一部分,返回一个新数组,原数组不会被修改。其语法为array.slice(start, end),其中start是起始索引(包括该索引的元素),end是结束索引(不包括该索引的元素),如果不传入end参数,则默认截取到数组末尾。例如:
javascript
const arr = [1, 2, 3, 4, 5];
const newArr = arr.slice(1, 3);
console.log(newArr);
console.log(arr);
在上述代码中,arr为[1, 2, 3, 4, 5],通过slice(1, 3),从索引1处开始截取到索引3(不包括3),得到新数组newArr为[2, 3],原数组arr保持不变。当我们需要获取数组中的一段数据,如从一个文章段落数组中获取中间的几个段落展示给用户时,slice()方法就能轻松实现。
(四)concat ()
concat()方法用于合并两个或多个数组,返回一个新的数组,原数组不会被改变。它可以接收一个或多个数组作为参数,也可以接收单个元素作为参数。例如:
javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const newArr = arr1.concat(arr2, 7);
console.log(newArr);
console.log(arr1);
console.log(arr2);
这里,arr1为[1, 2, 3],arr2为[4, 5, 6],通过concat()方法将arr1、arr2数组合并,并添加元素7,得到新数组newArr为[1, 2, 3, 4, 5, 6, 7],而arr1和arr2保持不变。在将多个小的数据数组合并成一个大数组时,concat()方法是非常便捷的选择。
(五)reduce ()
严格来说,reduce()方法并不直接返回一个新数组,它对数组中的每个元素执行一个提供的归约函数,将其结果汇总为单个返回值。不过,我们可以通过在回调函数中构建新数组等方式来达到类似返回新数组的效果。在基本的累加、累乘等操作中,原数组不会被修改。例如:
javascript
const arr = [1, 2, 3, 4, 5];
const sum = arr.reduce((acc, item) => acc + item, 0);
console.log(sum);
console.log(arr);
在这段代码中,arr为[1, 2, 3, 4, 5],通过reduce()方法计算数组元素的总和,sum为15,原数组arr保持不变。在对数据进行复杂的聚合操作,如统计一个包含多个子数组的数组中所有元素的特定属性之和时,reduce()方法能发挥强大的作用。
(六)some ()
some() 方法用于检测数组中是否至少有一个元素满足指定的条件。如果有一个元素满足条件,则返回 true,否则返回 false。该方法不会修改原数组。例如:
javascript
const numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven);
console.log(numbers);
在上述代码中,some() 方法检查数组 numbers 中是否有偶数。因为数组中有偶数,所以返回 true,而原数组 numbers 并未改变。当我们需要快速判断数组中是否存在符合特定条件的元素时,some() 方法就很有用,比如检查用户列表中是否有管理员用户。
(七)every ()
every() 方法用于检测数组中的所有元素是否都满足指定的条件。如果所有元素都满足条件,则返回 true,否则返回 false。同样,该方法不会修改原数组。例如:
javascript
const ages = [20, 25, 30, 35];
const allAdults = ages.every(age => age >= 18);
console.log(allAdults);
console.log(ages);
在这段代码中,every() 方法检查数组 ages 中的所有元素是否都大于等于 18 岁。由于所有元素都满足条件,所以返回 true,原数组 ages 保持不变。当我们需要确保数组中的每个元素都符合特定条件时,every() 方法就派上用场了,比如检查一个班级的学生是否都通过了考试。
(八)flat ()
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。原数组不会被修改。其语法为 array.flat([depth]),depth 表示要展开的深度,默认为 1。例如:
javascript
const nestedArray = [1, [2, [3, 4]]];
const flattenedArray = nestedArray.flat(2);
console.log(flattenedArray);
console.log(nestedArray);
在上述代码中,nestedArray 是一个嵌套数组,通过 flat(2) 方法将其展开到深度为 2 的层级,得到新数组 flattenedArray 为 [1, 2, 3, 4],原数组 nestedArray 保持不变。当处理多维数组并需要将其扁平化时,flat() 方法就非常实用。
(九)flatMap ()
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map() 方法后再调用 flat() 方法类似,但 flatMap() 更高效。该方法不会修改原数组。例如:
javascript
const arr = [1, 2, 3];
const newArr = arr.flatMap(num => [num * 2]);
console.log(newArr);
console.log(arr);
在这段代码中,arr 为 [1, 2, 3],通过 flatMap() 方法对每个元素乘以 2 并返回一个新数组 newArr 为 [2, 4, 6],原数组 arr 保持不变。当需要对数组元素进行映射并展开结果时,flatMap() 方法是一个不错的选择。
(十)find ()
find() 方法返回数组中满足提供的测试函数的第一个元素的值。如果没有找到符合条件的元素,则返回 undefined。该方法不会修改原数组。例如:
javascript
const numbers = [10, 20, 30, 40];
const found = numbers.find(num => num > 25);
console.log(found);
console.log(numbers);
在上述代码中,find() 方法在数组 numbers 中查找第一个大于 25 的元素,找到 30 并返回,原数组 numbers 保持不变。当我们需要从数组中查找第一个符合特定条件的元素时,find() 方法很有用。
(十一)findIndex ()
findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。如果没有找到符合条件的元素,则返回 -1。该方法不会修改原数组。例如:
javascript
const numbers = [10, 20, 30, 40];
const index = numbers.findIndex(num => num > 25);
console.log(index);
console.log(numbers);
在这段代码中,findIndex() 方法在数组 numbers 中查找第一个大于 25 的元素的索引,找到 30 对应的索引 2 并返回,原数组 numbers 保持不变。当我们需要获取数组中第一个符合特定条件的元素的索引时,findIndex() 方法就很合适。
(十二)includes ()
includes() 方法用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。该方法不会修改原数组。例如:
javascript
const arr = [1, 2, 3];
const hasTwo = arr.includes(2);
console.log(hasTwo);
console.log(arr);
在上述代码中,includes() 方法检查数组 arr 中是否包含值 2,因为包含,所以返回 true,原数组 arr 保持不变。当我们需要判断数组中是否存在某个特定值时,includes() 方法非常方便。