JavaScript数组
数组是JavaScript中用于存储多个值的有序集合,可以存储不同类型的数据,包括数字、字符串、对象、函数等。数组在JavaScript中是一种特殊的对象。
数组的概念
数组是一种线性数据结构,用于存储一组有序的值。每个值在数组中都有一个唯一的索引,从0开始计数。数组可以动态增长和收缩,不需要预先指定大小。
创建数组的方法
1. 数组字面量
使用方括号 [] 创建数组,是最常用的创建数组的方法。
// 数组字面量创建数组
const fruits = ['apple', 'banana', 'orange', 'grape'];
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, 'apple', true, { name: 'John' }];
console.log(fruits); // ['apple', 'banana', 'orange', 'grape']
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(mixed); // [1, 'apple', true, { name: 'John' }]2. 构造函数
使用 new Array() 构造函数创建数组。
// 构造函数创建数组
const emptyArray = new Array();
const numbers = new Array(1, 2, 3, 4, 5);
const singleElement = new Array(5); // 创建一个长度为5的空数组
console.log(emptyArray); // []
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(singleElement); // [empty × 5]
console.log(singleElement.length); // 53. Array.of()方法
使用 Array.of() 方法创建数组,与构造函数不同,它会将所有参数作为数组元素。
// Array.of()创建数组
const numbers = Array.of(1, 2, 3, 4, 5);
const singleElement = Array.of(5); // 创建包含一个元素5的数组
console.log(numbers); // [1, 2, 3, 4, 5]
console.log(singleElement); // [5]
console.log(singleElement.length); // 14. Array.from()方法
使用 Array.from() 方法从类数组对象或可迭代对象创建数组。
// Array.from()创建数组
const stringArray = Array.from('hello'); // 从字符串创建数组
const setArray = Array.from(new Set([1, 2, 3, 3, 4])); // 从Set创建数组,自动去重
const mapArray = Array.from(new Map([['a', 1], ['b', 2]])); // 从Map创建数组
console.log(stringArray); // ['h', 'e', 'l', 'l', 'o']
console.log(setArray); // [1, 2, 3, 4]
console.log(mapArray); // [['a', 1], ['b', 2]]
// 从类数组对象创建数组
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
const arrayFromLike = Array.from(arrayLike);
console.log(arrayFromLike); // ['a', 'b', 'c']访问数组元素
使用索引访问数组元素,索引从0开始计数。
const fruits = ['apple', 'banana', 'orange', 'grape'];
console.log(fruits[0]); // apple
console.log(fruits[1]); // banana
console.log(fruits[2]); // orange
console.log(fruits[3]); // grape
console.log(fruits[4]); // undefined(索引不存在)修改数组元素
使用索引修改数组元素的值。
const fruits = ['apple', 'banana', 'orange', 'grape'];
fruits[1] = 'mango'; // 修改索引为1的元素
console.log(fruits); // ['apple', 'mango', 'orange', 'grape']数组的长度
使用 length 属性获取或设置数组的长度。
const fruits = ['apple', 'banana', 'orange', 'grape'];
console.log(fruits.length); // 4
// 修改数组长度
fruits.length = 2; // 截断数组,只保留前2个元素
console.log(fruits); // ['apple', 'banana']
fruits.length = 5; // 扩展数组,新增的元素为undefined
console.log(fruits); // ['apple', 'banana', undefined, undefined, undefined]数组的基本操作
添加元素
1. push()方法
在数组末尾添加一个或多个元素,并返回新的长度。
const fruits = ['apple', 'banana'];
const newLength = fruits.push('orange', 'grape');
console.log(fruits); // ['apple', 'banana', 'orange', 'grape']
console.log(newLength); // 42. unshift()方法
在数组开头添加一个或多个元素,并返回新的长度。
const fruits = ['apple', 'banana'];
const newLength = fruits.unshift('orange', 'grape');
console.log(fruits); // ['orange', 'grape', 'apple', 'banana']
console.log(newLength); // 4删除元素
1. pop()方法
删除数组末尾的元素,并返回被删除的元素。
const fruits = ['apple', 'banana', 'orange'];
const removed = fruits.pop();
console.log(fruits); // ['apple', 'banana']
console.log(removed); // orange2. shift()方法
删除数组开头的元素,并返回被删除的元素。
const fruits = ['apple', 'banana', 'orange'];
const removed = fruits.shift();
console.log(fruits); // ['banana', 'orange']
console.log(removed); // apple3. delete关键字
使用 delete 关键字删除数组元素,会留下undefined。
const fruits = ['apple', 'banana', 'orange'];
delete fruits[1];
console.log(fruits); // ['apple', undefined, 'orange']
console.log(fruits.length); // 3(长度不变)数组的遍历
1. for循环
使用传统的for循环遍历数组。
const numbers = [1, 2, 3, 4, 5];
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
// 输出:1 2 3 4 52. for...of循环
使用for...of循环遍历数组元素。
const numbers = [1, 2, 3, 4, 5];
for (const number of numbers) {
console.log(number);
}
// 输出:1 2 3 4 53. forEach()方法
使用 forEach() 方法遍历数组,对每个元素执行回调函数。
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(number, index, array) {
console.log(`Index ${index}: ${number}`);
});
// 输出:
// Index 0: 1
// Index 1: 2
// Index 2: 3
// Index 3: 4
// Index 4: 54. map()方法
使用 map() 方法遍历数组,返回一个新数组,包含每个元素调用回调函数的结果。
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(function(number) {
return number * 2;
});
console.log(doubled); // [2, 4, 6, 8, 10]
console.log(numbers); // [1, 2, 3, 4, 5](原数组不变)数组的搜索和排序
搜索元素
1. indexOf()方法
返回元素在数组中第一次出现的索引,如果不存在则返回-1。
const fruits = ['apple', 'banana', 'orange', 'banana'];
console.log(fruits.indexOf('banana')); // 1
console.log(fruits.indexOf('grape')); // -12. lastIndexOf()方法
返回元素在数组中最后一次出现的索引,如果不存在则返回-1。
const fruits = ['apple', 'banana', 'orange', 'banana'];
console.log(fruits.lastIndexOf('banana')); // 3
console.log(fruits.lastIndexOf('grape')); // -13. includes()方法
判断数组是否包含某个元素,返回布尔值。
const fruits = ['apple', 'banana', 'orange'];
console.log(fruits.includes('banana')); // true
console.log(fruits.includes('grape')); // false4. find()方法
返回数组中第一个满足条件的元素,如果不存在则返回undefined。
const numbers = [1, 2, 3, 4, 5];
const even = numbers.find(function(number) {
return number % 2 === 0;
});
console.log(even); // 25. findIndex()方法
返回数组中第一个满足条件的元素的索引,如果不存在则返回-1。
const numbers = [1, 2, 3, 4, 5];
const evenIndex = numbers.findIndex(function(number) {
return number % 2 === 0;
});
console.log(evenIndex); // 1排序数组
1. sort()方法
对数组元素进行排序,默认按照字符串Unicode码点排序。
const fruits = ['banana', 'apple', 'orange', 'grape'];
fruits.sort();
console.log(fruits); // ['apple', 'banana', 'grape', 'orange']
// 数字排序(需要自定义比较函数)
const numbers = [10, 2, 23, 1, 5];
numbers.sort(function(a, b) {
return a - b; // 升序排序
});
console.log(numbers); // [1, 2, 5, 10, 23]
numbers.sort(function(a, b) {
return b - a; // 降序排序
});
console.log(numbers); // [23, 10, 5, 2, 1]2. reverse()方法
反转数组元素的顺序。
const numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers); // [5, 4, 3, 2, 1]数组的切片和连接
1. 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()方法
连接两个或多个数组,返回一个新数组,不会修改原数组。
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'](原数组不变)3. 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']数组的其他方法
1. 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'2. reduce()方法
对数组元素执行累加器函数,返回一个值。
const numbers = [1, 2, 3, 4, 5];
// 求和
const sum = numbers.reduce(function(accumulator, currentValue) {
return accumulator + currentValue;
}, 0);
console.log(sum); // 15
// 求最大值
const max = numbers.reduce(function(accumulator, currentValue) {
return Math.max(accumulator, currentValue);
}, -Infinity);
console.log(max); // 53. filter()方法
返回数组中满足条件的元素,组成新数组。
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(function(number) {
return number % 2 === 0;
});
console.log(evenNumbers); // [2, 4]数组的最佳实践
- 使用数组字面量创建数组,简洁易读
- 使用for...of或forEach()遍历数组,避免传统for循环的索引错误
- 使用map()、filter()、reduce()等方法进行函数式编程
- 注意sort()方法的默认排序行为,数字排序需要自定义比较函数
- 避免使用delete关键字删除数组元素,使用splice()或pop()/shift()
- 使用includes()方法判断元素是否存在,比indexOf()更直观
- 考虑使用扩展运算符(...)进行数组操作,如复制、合并等
- 注意数组的引用特性,修改数组会影响所有引用该数组的变量