JavaScript 数组方法
JavaScript 数组方法
Section titled “JavaScript 数组方法”JavaScript 数组拥有一套丰富的内置方法,用于执行常见的操作,例如添加/移除元素、迭代、转换等。理解这些方法是高效的 JavaScript 编程的关键。
将数组转换为字符串
Section titled “将数组转换为字符串”toString() 方法将数组转换为一个由其元素组成的逗号分隔字符串。
const fruits = ["Banana", "Orange", "Apple", "Mango"];console.log(fruits.toString()); // Output: "Banana,Orange,Apple,Mango"join() 方法也将所有数组元素连接成一个字符串,但允许你指定分隔符。
const fruits = ["Banana", "Orange", "Apple", "Mango"];console.log(fruits.join(" * ")); // Output: "Banana * Orange * Apple * Mango"console.log(fruits.join(" - ")); // Output: "Banana - Orange - Apple - Mango"添加和移除元素(可变方法)
Section titled “添加和移除元素(可变方法)”这些方法会修改原始数组。
pop(): 移除数组的最后一个元素,并返回该元素。
const fruits = ["Banana", "Orange", "Apple", "Mango"];const lastFruit = fruits.pop();console.log(lastFruit); // Output: "Mango"console.log(fruits); // Output: ["Banana", "Orange", "Apple"]push(): 向数组末尾添加一个或多个新元素,并返回数组的新长度。
const fruits = ["Banana", "Orange", "Apple"];const newLength = fruits.push("Kiwi", "Lemon");console.log(newLength); // Output: 5console.log(fruits); // Output: ["Banana", "Orange", "Apple", "Kiwi", "Lemon"]shift(): 移除数组的第一个元素,并返回该元素。此操作会将所有后续元素移至较低的索引位置。
const fruits = ["Banana", "Orange", "Apple"];const firstFruit = fruits.shift();console.log(firstFruit); // Output: "Banana"console.log(fruits); // Output: ["Orange", "Apple"]unshift(): 向数组开头添加一个或多个新元素,并返回数组的新长度。此操作会将现有元素移至较高的索引位置。
const fruits = ["Orange", "Apple"];const newLengthUnshift = fruits.unshift("Lemon", "Pineapple");console.log(newLengthUnshift); // Output: 4console.log(fruits); // Output: ["Lemon", "Pineapple", "Orange", "Apple"]splice(): 一个强大的方法,通过移除或替换现有元素以及/或在原位置添加新元素来改变数组的内容。它返回一个包含被删除元素的数组。
语法: array.splice(startIndex, deleteCount, item1, item2, ...)
const fruits = ["Banana", "Orange", "Apple", "Mango"];// Add elements: At index 2, remove 0 elements, add "Lemon", "Kiwi"fruits.splice(2, 0, "Lemon", "Kiwi");console.log(fruits); // Output: ["Banana", "Orange", "Lemon", "Kiwi", "Apple", "Mango"]
// Remove elements: At index 0, remove 1 elementconst removed = fruits.splice(0, 1);console.log(removed); // Output: ["Banana"]console.log(fruits); // Output: ["Orange", "Lemon", "Kiwi", "Apple", "Mango"]
// Replace elements: At index 1, remove 2 elements, add "Grape"fruits.splice(1, 2, "Grape");console.log(fruits); // Output: ["Orange", "Grape", "Apple", "Mango"]注意: 使用 delete array[index] 会在数组中创建 undefined 的“空洞”。通常最好使用 splice()、pop() 或 shift() 来移除元素。
从现有数组创建新数组(不变方法)
Section titled “从现有数组创建新数组(不变方法)”这些方法返回一个新数组,并且不修改原始数组。
concat(): 合并两个或多个数组(或值)以创建一个新数组。
const arr1 = ["Cecilie", "Lone"];const arr2 = ["Emil", "Tobias"];const arr3 = ["Robin"];const children = arr1.concat(arr2, arr3, "Peter");console.log(children); // Output: ["Cecilie", "Lone", "Emil", "Tobias", "Robin", "Peter"]console.log(arr1); // Output: ["Cecilie", "Lone"] (original unchanged)使用展开语法(...)是用于连接数组的一种现代替代方法:
const newChildren = [...arr1, ...arr2, ...arr3, "Peter"];console.log(newChildren);slice(): 提取数组的一部分并返回一个新数组。原始数组不会被修改。
语法: array.slice(startIndex, endIndex) (endIndex 不包含在内)
const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];const citrus = fruits.slice(1, 3); // Elements from index 1 up to (but not including) index 3console.log(citrus); // Output: ["Orange", "Lemon"]
const endFruits = fruits.slice(2); // Elements from index 2 to the endconsole.log(endFruits); // Output: ["Lemon", "Apple", "Mango"]
const shallowCopy = fruits.slice(); // Creates a shallow copy of the arrayconsole.log(shallowCopy);展开语法(...)也常用于浅拷贝数组:
const spreadCopy = [...fruits];console.log(spreadCopy);sort(): 在原位置对数组元素进行排序,并返回排序后的数组。默认情况下,它将元素按字符串(字典顺序)进行排序。
const fruits = ["Banana", "Orange", "Apple", "Mango"];fruits.sort();console.log(fruits); // Output: ["Apple", "Banana", "Mango", "Orange"]
const numbers = [40, 100, 1, 5, 25, 10];numbers.sort(); // Incorrect numeric sort!console.log(numbers); // Output: [1, 10, 100, 25, 40, 5] (sorted as strings)**数值排序:**要正确地对数字进行排序,你必须提供一个比较函数(compare function)。
const points = [40, 100, 1, 5, 25, 10];// Ascending orderpoints.sort(function(a, b) { return a - b; });// Using arrow function: points.sort((a, b) => a - b);console.log(points); // Output: [1, 5, 10, 25, 40, 100]
// Descending orderpoints.sort(function(a, b) { return b - a; });// Using arrow function: points.sort((a, b) => b - a);console.log(points); // Output: [100, 40, 25, 10, 5, 1]比较函数 (a, b) 应返回:如果 a 应该在 b 之前,则返回负值;如果 a 应该在 b 之后,则返回正值;如果它们的顺序无关紧要,则返回零。
reverse(): 在原位置颠倒数组元素的顺序,并返回颠倒后的数组。
const fruits = ["Banana", "Orange", "Apple"];fruits.reverse();console.log(fruits); // Output: ["Apple", "Orange", "Banana"]现代迭代和转换方法(ES5+)
Section titled “现代迭代和转换方法(ES5+)”这些方法通常比手动 for 循环更受欢迎,因为它们更简洁、更富有表达力。除非另有说明(例如 forEach 的回调函数内部),否则它们不会修改原始数组。
forEach(callbackFn): 对数组中的每个元素执行一次提供的函数。
const numbers = [1, 2, 3];numbers.forEach(function(number, index, array) { console.log(`Element at index ${index}: ${number}`);});map(callbackFn): 创建一个新数组,其中包含对调用数组中的每个元素执行提供的函数所得到的结果。
const numbers = [1, 4, 9];const roots = numbers.map(function(num) { return Math.sqrt(num);});// Using arrow function: const roots = numbers.map(num => Math.sqrt(num));console.log(roots); // Output: [1, 2, 3]filter(callbackFn): 创建一个新数组,其中包含通过提供的函数实现的测试的所有元素。
const numbers = [1, 2, 3, 4, 5, 6];const evens = numbers.filter(function(num) { return num % 2 === 0;});// Using arrow function: const evens = numbers.filter(num => num % 2 === 0);console.log(evens); // Output: [2, 4, 6]reduce(callbackFn, initialValue): 在数组的每个元素上执行一个 reducer 函数,最终得到一个单一的输出值。
const numbers = [1, 2, 3, 4];const sum = numbers.reduce(function(accumulator, currentValue) { return accumulator + currentValue;}, 0); // 0 is the initialValue for accumulator// Using arrow function: const sum = numbers.reduce((acc, val) => acc + val, 0);console.log(sum); // Output: 10find(callbackFn): 返回数组中满足提供的测试函数的第一个元素。否则,返回 undefined。
const numbers = [10, 20, 35, 40];const found = numbers.find(num => num > 30);console.log(found); // Output: 35findIndex(callbackFn): 返回数组中满足提供的测试函数的第一个元素的索引。否则,返回 -1。
const numbers = [10, 20, 35, 40];const foundIndex = numbers.findIndex(num => num > 30);console.log(foundIndex); // Output: 2some(callbackFn): 测试数组中是否至少有一个元素通过了提供的函数实现的测试。返回布尔值。
const numbers = [1, 3, 5, 7, 8];const hasEven = numbers.some(num => num % 2 === 0);console.log(hasEven); // Output: trueevery(callbackFn): 测试数组中的所有元素是否都通过了提供的函数实现的测试。返回布尔值。
const numbers = [2, 4, 6, 8];const allEven = numbers.every(num => num % 2 === 0);console.log(allEven); // Output: trueincludes(valueToFind, fromIndex): 确定数组是否包含某个值,返回 true 或 false。
const pets = ['cat', 'dog', 'bat'];console.log(pets.includes('cat')); // Output: trueconsole.log(pets.includes('at')); // Output: false (checks for whole element)console.log(pets.includes('dog', 1)); // Output: true (starts search from index 1)其他常用方法(ES6+)
Section titled “其他常用方法(ES6+)”Array.from(arrayLikeOrIterable): 从类数组对象或可迭代对象创建一个新的、浅拷贝的 Array 实例。
const str = "hello";const chars = Array.from(str);console.log(chars); // Output: ['h', 'e', 'l', 'l', 'o']
function getArgs() { return Array.from(arguments);}console.log(getArgs(1, 'a', true)); // Output: [1, 'a', true]flat(depth): 创建一个新数组,其中所有子数组元素根据指定的深度递归地连接到新数组中。
const arr = [1, [2, [3, 4]], 5];console.log(arr.flat()); // Output: [1, 2, [3, 4], 5] (depth 1)console.log(arr.flat(2)); // Output: [1, 2, 3, 4, 5]console.log(arr.flat(Infinity)); // Output: [1, 2, 3, 4, 5]flatMap(callbackFn): 首先使用映射函数映射每个元素,然后将结果展平为一个新数组。它与 a.map(...args).flat() 相同,但效率稍高。
const arr = [1, 2, 3];const result = arr.flatMap(x => [x, x * 2]);console.log(result); // Output: [1, 2, 2, 4, 3, 6]在数组中查找最大/最小值
Section titled “在数组中查找最大/最小值”虽然可以使用 sort(),但这并不是查找单个最高或最低值最有效的方式。请使用 Math.max() 或 Math.min() 配合展开语法(spread syntax),或者使用 reduce()。
const points = [40, 100, 1, 5, 25, 10];
// Using Math.max/min with spread operatorconst highest = Math.max(...points);const lowest = Math.min(...points);console.log(`Highest: ${highest}, Lowest: ${lowest}`); // Highest: 100, Lowest: 1
// Using reduceconst highestReduce = points.reduce((max, current) => Math.max(max, current), -Infinity);const lowestReduce = points.reduce((min, current) => Math.min(min, current), Infinity);console.log(`Highest (reduce): ${highestReduce}, Lowest (reduce): ${lowestReduce}`);完整 Array 参考
Section titled “完整 Array 参考”JavaScript 数组还有许多其他方法。要获取包含所有 Array 属性和方法的详细描述、语法和示例的完整参考,请查阅 MDN Web 文档中关于 JavaScript Array 对象的内容。