JavaScript数组方法

JavaScript数组提供了丰富的方法,用于遍历、修改、访问和操作数组元素。这些方法可以帮助我们更高效地处理数组数据。

数组遍历方法

1. forEach()

forEach() 方法对数组的每个元素执行一次提供的函数。

// forEach()示例
const numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(number, index, array) {
  console.log(`Index ${index}: ${number}`);
});

// 使用箭头函数
numbers.forEach(number => console.log(number * 2));

2. map()

map() 方法创建一个新数组,其结果是该数组中的每个元素调用一次提供的函数后的返回值。

// map()示例
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2);

console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5](原数组不变)

// 将字符串数组转换为长度数组
const words = ['apple', 'banana', 'orange'];
const wordLengths = words.map(word => word.length);
console.log(wordLengths); // [5, 6, 6]

3. filter()

filter() 方法创建一个新数组,包含通过所提供函数实现的测试的所有元素。

// filter()示例
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evenNumbers = numbers.filter(number => number % 2 === 0);

console.log(evenNumbers); // [2, 4, 6, 8, 10]

// 过滤出长度大于5的字符串
const words = ['apple', 'banana', 'orange', 'grape', 'kiwi'];
const longWords = words.filter(word => word.length > 5);
console.log(longWords); // ['banana', 'orange']

4. reduce()

reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

// reduce()示例
const numbers = [1, 2, 3, 4, 5];

// 求和
const sum = numbers.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
}, 0);
console.log(sum); // 15

// 求乘积
const product = numbers.reduce((accumulator, currentValue) => {
  return accumulator * currentValue;
}, 1);
console.log(product); // 120

// 求最大值
const max = numbers.reduce((accumulator, currentValue) => {
  return Math.max(accumulator, currentValue);
}, -Infinity);
console.log(max); // 5

// 将数组转换为对象
const fruits = ['apple', 'banana', 'orange'];
const fruitObject = fruits.reduce((obj, fruit, index) => {
  obj[index] = fruit;
  return obj;
}, {});
console.log(fruitObject); // {0: 'apple', 1: 'banana', 2: 'orange'}

5. reduceRight()

reduceRight() 方法的功能和 reduce() 一样,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。

// reduceRight()示例
const numbers = [1, 2, 3, 4, 5];
const reversedSum = numbers.reduceRight((accumulator, currentValue) => {
  return accumulator + currentValue;
}, 0);
console.log(reversedSum); // 15(结果与reduce相同,但处理顺序相反)

// 连接字符串
const words = ['Hello', ' ', 'world', '!'];
const sentence = words.reduceRight((accumulator, currentValue) => {
  return currentValue + accumulator;
});
console.log(sentence); // '!world Hello'(注意顺序)

6. some()

some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。返回一个Boolean类型的值。

// some()示例
const numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some(number => number % 2 === 0);
console.log(hasEven); // true(数组中至少有一个偶数)

const hasNegative = numbers.some(number => number < 0);
console.log(hasNegative); // false(数组中没有负数)

7. every()

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。返回一个Boolean类型的值。

// every()示例
const numbers = [2, 4, 6, 8, 10];
const allEven = numbers.every(number => number % 2 === 0);
console.log(allEven); // true(所有元素都是偶数)

const allPositive = numbers.every(number => number > 0);
console.log(allPositive); // true(所有元素都是正数)

const mixedNumbers = [1, 2, 3, 4, 5];
const allEvenMixed = mixedNumbers.every(number => number % 2 === 0);
console.log(allEvenMixed); // false(不是所有元素都是偶数)

数组修改方法

1. push()

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

// push()示例
const fruits = ['apple', 'banana'];
const newLength = fruits.push('orange', 'grape');

console.log(fruits); // ['apple', 'banana', 'orange', 'grape']
console.log(newLength); // 4

2. pop()

pop() 方法从数组中删除最后一个元素,并返回该元素的值。此方法会更改数组的长度。

// pop()示例
const fruits = ['apple', 'banana', 'orange'];
const removed = fruits.pop();

console.log(fruits); // ['apple', 'banana']
console.log(removed); // orange

3. unshift()

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

// unshift()示例
const fruits = ['apple', 'banana'];
const newLength = fruits.unshift('orange', 'grape');

console.log(fruits); // ['orange', 'grape', 'apple', 'banana']
console.log(newLength); // 4

4. shift()

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

// shift()示例
const fruits = ['apple', 'banana', 'orange'];
const removed = fruits.shift();

console.log(fruits); // ['banana', 'orange']
console.log(removed); // apple

5. splice()

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。

// splice()示例
const fruits = ['apple', 'banana', 'orange', 'grape'];

// 删除元素:splice(start, deleteCount)
const removed = fruits.splice(1, 2); // 从索引1开始删除2个元素
console.log(fruits); // ['apple', 'grape']
console.log(removed); // ['banana', 'orange']

// 添加元素:splice(start, 0, item1, item2, ...)
fruits.splice(1, 0, 'mango', 'kiwi'); // 从索引1开始添加元素
console.log(fruits); // ['apple', 'mango', 'kiwi', 'grape']

// 替换元素:splice(start, deleteCount, item1, item2, ...)
fruits.splice(2, 1, 'pineapple'); // 从索引2开始删除1个元素,添加1个元素
console.log(fruits); // ['apple', 'mango', 'pineapple', 'grape']

6. sort()

sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。

// sort()示例
const fruits = ['banana', 'apple', 'orange', 'grape'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'grape', 'orange']

// 数字排序(需要自定义比较函数)
const numbers = [10, 2, 23, 1, 5];

// 升序排序
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 5, 10, 23]

// 降序排序
numbers.sort((a, b) => b - a);
console.log(numbers); // [23, 10, 5, 2, 1]

// 按字符串长度排序
const words = ['apple', 'banana', 'orange', 'grape', 'kiwi'];
words.sort((a, b) => a.length - b.length);
console.log(words); // ['kiwi', 'apple', 'grape', 'banana', 'orange']

7. reverse()

reverse() 方法将数组中元素的位置颠倒,并返回该数组。该方法会改变原数组。

// reverse()示例
const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // [5, 4, 3, 2, 1]

const fruits = ['apple', 'banana', 'orange'];
fruits.reverse();
console.log(fruits); // ['orange', 'banana', 'apple']

数组访问方法

1. slice()

slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。

// slice()示例
const fruits = ['apple', 'banana', 'orange', 'grape', 'mango'];

// slice(start, end),end不包含在内
const slice1 = fruits.slice(1, 3); // 从索引1到3(不包含3)
const slice2 = fruits.slice(2); // 从索引2到末尾
const slice3 = fruits.slice(-2); // 从倒数第2个到末尾
const slice4 = fruits.slice(1, -1); // 从索引1到倒数第1个(不包含)

console.log(slice1); // ['banana', 'orange']
console.log(slice2); // ['orange', 'grape', 'mango']
console.log(slice3); // ['grape', 'mango']
console.log(slice4); // ['banana', 'orange', 'grape']
console.log(fruits); // ['apple', 'banana', 'orange', 'grape', 'mango'](原数组不变)

2. concat()

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

// concat()示例
const fruits1 = ['apple', 'banana'];
const fruits2 = ['orange', 'grape'];
const fruits3 = ['mango', 'pineapple'];

const combined = fruits1.concat(fruits2, fruits3);
console.log(combined); // ['apple', 'banana', 'orange', 'grape', 'mango', 'pineapple']
console.log(fruits1); // ['apple', 'banana'](原数组不变)

// 使用扩展运算符实现相同效果
const combinedWithSpread = [...fruits1, ...fruits2, ...fruits3];
console.log(combinedWithSpread); // ['apple', 'banana', 'orange', 'grape', 'mango', 'pineapple']

3. join()

join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。

// join()示例
const fruits = ['apple', 'banana', 'orange'];

console.log(fruits.join()); // 'apple,banana,orange'
console.log(fruits.join(', ')); // 'apple, banana, orange'
console.log(fruits.join('-')); // 'apple-banana-orange'
console.log(fruits.join('')); // 'applebananaorange'
console.log(fruits.join(' ')); // 'apple banana orange'

4. indexOf()

indexOf() 方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。

// indexOf()示例
const fruits = ['apple', 'banana', 'orange', 'banana'];

console.log(fruits.indexOf('banana')); // 1
console.log(fruits.indexOf('grape')); // -1
console.log(fruits.indexOf('banana', 2)); // 3(从索引2开始搜索)

5. lastIndexOf()

lastIndexOf() 方法返回指定元素(也即有效的JavaScript值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。

// lastIndexOf()示例
const fruits = ['apple', 'banana', 'orange', 'banana'];

console.log(fruits.lastIndexOf('banana')); // 3
console.log(fruits.lastIndexOf('grape')); // -1
console.log(fruits.lastIndexOf('banana', 2)); // 1(从索引2开始向前搜索)

6. includes()

includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。

// includes()示例
const fruits = ['apple', 'banana', 'orange'];

console.log(fruits.includes('banana')); // true
console.log(fruits.includes('grape')); // false
console.log(fruits.includes('apple', 1)); // false(从索引1开始搜索)

7. find()

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

// find()示例
const numbers = [1, 2, 3, 4, 5];
const even = numbers.find(number => number % 2 === 0);
console.log(even); // 2

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];
const user = users.find(user => user.id === 2);
console.log(user); // { id: 2, name: 'Bob' }

8. findIndex()

findIndex() 方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

// findIndex()示例
const numbers = [1, 2, 3, 4, 5];
const evenIndex = numbers.findIndex(number => number % 2 === 0);
console.log(evenIndex); // 1

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];
const userIndex = users.findIndex(user => user.id === 3);
console.log(userIndex); // 2
const notFoundIndex = users.findIndex(user => user.id === 4);
console.log(notFoundIndex); // -1

数组的其他方法

1. fill()

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

// fill()示例
const array1 = [1, 2, 3, 4, 5];

// 用0填充整个数组
console.log(array1.fill(0)); // [0, 0, 0, 0, 0]

// 用5填充索引1到3的位置(不包括3)
const array2 = [1, 2, 3, 4, 5];
console.log(array2.fill(5, 1, 3)); // [1, 5, 5, 4, 5]

// 用10填充从索引2到末尾的位置
const array3 = [1, 2, 3, 4, 5];
console.log(array3.fill(10, 2)); // [1, 2, 10, 10, 10]

2. copyWithin()

copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。

// copyWithin()示例
const array1 = [1, 2, 3, 4, 5];

// 复制索引0到2的元素到索引3的位置
console.log(array1.copyWithin(3, 0, 2)); // [1, 2, 3, 1, 2]

const array2 = [1, 2, 3, 4, 5];
// 复制索引1到末尾的元素到索引0的位置
console.log(array2.copyWithin(0, 1)); // [2, 3, 4, 5, 5]

3. flat()

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

// flat()示例
const nestedArray = [1, 2, [3, 4, [5, 6]]];

// 默认深度为1
console.log(nestedArray.flat()); // [1, 2, 3, 4, [5, 6]]

// 深度为2
console.log(nestedArray.flat(2)); // [1, 2, 3, 4, 5, 6]

// 深度为Infinity,扁平化所有嵌套数组
console.log(nestedArray.flat(Infinity)); // [1, 2, 3, 4, 5, 6]

4. flatMap()

flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。

// flatMap()示例
const numbers = [1, 2, 3, 4, 5];

// 先map后flat
const result1 = numbers.map(x => [x * 2]).flat();
console.log(result1); // [2, 4, 6, 8, 10]

// 使用flatMap
const result2 = numbers.flatMap(x => [x * 2]);
console.log(result2); // [2, 4, 6, 8, 10]

// 更复杂的例子
const words = ['hello', 'world'];
const letters = words.flatMap(word => word.split(''));
console.log(letters); // ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']

5. Array.from()

Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

// Array.from()示例
const string = 'hello';
console.log(Array.from(string)); // ['h', 'e', 'l', 'l', 'o']

const set = new Set([1, 2, 3, 3, 4]);
console.log(Array.from(set)); // [1, 2, 3, 4](自动去重)

const map = new Map([['a', 1], ['b', 2]]);
console.log(Array.from(map)); // [['a', 1], ['b', 2]]

// 使用映射函数
const numbers = [1, 2, 3, 4, 5];
const doubled = Array.from(numbers, x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

数组方法的最佳实践

  1. 使用函数式编程方法:优先使用 map()、filter()、reduce() 等函数式编程方法,使代码更简洁、易读。
  2. 避免修改原数组:在不需要修改原数组时,使用 slice()、concat()、map() 等不会修改原数组的方法。
  3. **使用 includes() 代替 indexOf()**:判断元素是否存在时,使用 includes() 方法更直观,返回布尔值。
  4. 使用 find() 和 findIndex() 查找元素:查找满足条件的元素或索引时,使用 find() 和 findIndex() 方法更高效。
  5. 注意 sort() 方法的默认行为:sort() 方法默认按照字符串排序,数字排序需要自定义比较函数。
  6. 使用扩展运算符简化操作:使用扩展运算符(...)简化数组的复制、合并等操作。
  7. 使用 flat() 和 flatMap() 处理嵌套数组:处理嵌套数组时,使用 flat() 和 flatMap() 方法更方便。
  8. 合理选择遍历方法
    • 不需要返回新数组时,使用 forEach()
    • 需要返回新数组时,使用 map()
    • 需要筛选元素时,使用 filter()
    • 需要汇总结果时,使用 reduce()
    • 需要判断元素是否存在时,使用 some() 或 every()
« 上一篇 JavaScript对象方法 下一篇 » JavaScript JSON