数组
声明语法
let 数组名 = [数据1,数据2,...,数据n]
js的数组很像py的列表,但是更厉害之处是可以存不同数据类型,这也可能导致数据类型出错
可以使用下标索引 可以嵌套数组 可以自由拓展
关于数组的函数
以下是一些最常用的数组方法:
0. length返回长度
1. push() - 在数组末尾添加一个或多个元素,并返回新的长度
const fruits = ['apple', 'banana'];
let len = fruits.push('orange');
console.log(fruits);// 输出: ['apple', 'banana', 'orange']
console.log(len); //输出:3
2. pop() - 删除并返回数组的最后一个元素
const fruits = ['apple', 'banana', 'orange'];
const lastFruit = fruits.pop();
console.log(lastFruit); // 输出: 'orange'
console.log(fruits); // 输出: ['apple', 'banana']
3. unshift() - 在数组开头添加一个或多个元素,并返回新的长度
const numbers = [2, 3, 4];
numbers.unshift(1);
console.log(numbers); // 输出: [1, 2, 3, 4]
4. shift() - 删除并返回数组的第一个元素
const numbers = [1, 2, 3, 4];
const firstNumber = numbers.shift();
console.log(firstNumber); // 输出: 1
console.log(numbers); // 输出: [2, 3, 4]
5. indexOf() - 返回指定元素在数组中的第一个索引,如果不存在则返回 -1
const fruits = ['apple', 'banana', 'orange', 'apple'];
console.log(fruits.indexOf('banana')); // 输出: 1
console.log(fruits.indexOf('grape')); // 输出: -1
6. slice() - 返回数组的一个浅拷贝,包含从开始到结束(不包括结束)的元素
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2, 4)); // 输出: ['camel', 'duck']
7. splice() - 通过删除或替换现有元素和/或添加新元素来修改数组
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
console.log(months); // 输出: ['Jan', 'Feb', 'March', 'April', 'June']
对splice的拓展: 区别于delete操作符 因为delete会造成数组空洞,其他都是缩进 语法:
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
参数
start: 指定修改的开始位置(从0计数)。- 如果大于数组长度,则从数组末尾开始添加内容。
- 如果为负值,则表示从数组末位开始的第几位(从-1计数)。
deleteCount(可选): 整数,表示要移除的元素个数。- 如果省略,则默认从
start到数组结尾的所有元素都将被删除。
- 如果省略,则默认从
item1, item2, ...(可选): 要添加进数组的元素,从start位置开始。如果不指定,则splice()将只删除数组元素。
返回值
splice() 方法返回一个由被删除的元素组成的数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。
使用示例
- 删除元素
const fruits = ['apple', 'banana', 'orange', 'mango'];
const removed = fruits.splice(1, 2);
console.log(fruits); // 输出: ['apple', 'mango']
console.log(removed); // 输出: ['banana', 'orange']
- 添加元素
const numbers = [1, 2, 5];
numbers.splice(2, 0, 3, 4);
console.log(numbers); // 输出: [1, 2, 3, 4, 5]
3. 替换元素
const colors = ['red', 'green', 'blue'];
colors.splice(1, 1, 'yellow', 'purple');
console.log(colors); // 输出: ['red', 'yellow', 'purple', 'blue']
- 使用负索引
const animals = ['lion', 'elephant', 'giraffe', 'zebra'];
animals.splice(-2, 1, 'hippo');
console.log(animals); // 输出: ['lion', 'elephant', 'hippo', 'zebra']
- 删除数组末尾的元素
const letters = ['a', 'b', 'c', 'd', 'e'];
letters.splice(3);
console.log(letters); // 输出: ['a', 'b', 'c']
注意事项
splice()方法会直接修改原数组。- 如果你只想复制一个数组的一部分,而不修改原数组,可以使用
slice()方法。 - 当用于大型数组时,
splice()可能会影响性能,因为它可能需要重新索引数组的大部分内容。
8. forEach() - 对数组的每个元素执行一次给定的函数
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(num => console.log(num * 2));
// 输出:
// 2
// 4
// 6
// 8
// 10
对于forEach()函数的进一步解释: 语法
array.forEach(callback(currentValue [, index [, array]])[, thisArg])
参数
-
callback: 为数组中每个元素执行的函数,该函数接受一至三个参数:currentValue: 数组中正在处理的当前元素。index(可选): 数组中正在处理的当前元素的索引。array(可选):forEach()方法正在操作的数组。
-
thisArg(可选): 执行callback函数时使用的this值。
返回值
forEach() 方法总是返回 undefined。
使用示例
- 基本用法
const fruits = ['apple', 'banana', 'orange'];
fruits.forEach(function(fruit) {
console.log(fruit);
});
// 输出:
// apple
// banana
// orange
- 使用箭头函数
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(number => console.log(number * 2));
// 输出:
// 2
// 4
// 6
// 8
// 10
- 使用索引参数
const colors = ['red', 'green', 'blue'];
colors.forEach((color, index) => {
console.log(\`Color at index \${index} is \${color}\`);
});
// 输出:
// Color at index 0 is red
// Color at index 1 is green
// Color at index 2 is blue
- 修改原数组
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((number, index, array) => {
array[index] = number * 2;
});
console.log(numbers);
// 输出: [2, 4, 6, 8, 10]
5. 使用 thisArg
class Counter {
constructor() {
this.count = 0;
}
increment() {
this.count++;
}
}
const counter = new Counter();
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(counter.increment, counter);
console.log(counter.count); // 输出: 5
注意事项
forEach()不会修改原数组(除非在回调函数中执行修改操作)。forEach()总是会遍历整个数组,无法中途停止(除非抛出异常)。如果需要中途停止遍历,可以考虑使用for循环或some()、every()等其他数组方法。forEach()不会对未初始化的值进行操作。forEach()是同步方法,不适合处理异步操作。对于异步操作,可以考虑使用for...of循环或Promise.all()。- 与
map()不同,forEach()没有返回值。如果需要根据原数组创建新数组,应该使用map()。
9. map() - 创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后的返回值
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // 输出: [2, 4, 6, 8, 10]
对map()函数的进一步解释: 语法:
let newArray = arr.map(callback(currentValue[, index[, array]]) {
// return element for newArray
}[, thisArg])
参数
callback: 生成新数组元素的函数,使用三个参数:currentValue: 数组中正在处理的当前元素。index(可选): 数组中正在处理的当前元素的索引。array(可选):map方法被调用的数组。
thisArg(可选): 执行callback函数时使用的this值。
返回值
一个新数组,每个元素都是回调函数的结果。
使用示例
- 基本用法:将数字数组中的每个元素翻倍
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = numbers.map(num => num * 2);
console.log(doubledNumbers); // 输出: [2, 4, 6, 8, 10]
- 处理对象数组:提取特定属性
const users = [
{ name: 'John', age: 30 },
{ name: 'Jane', age: 28 },
{ name: 'Bob', age: 35 }
];
const names = users.map(user => user.name);
console.log(names); // 输出: ['John', 'Jane', 'Bob']
3. 使用索引参数
const letters = ['a', 'b', 'c'];
const indexedLetters = letters.map((letter, index) => \`\${letter.toUpperCase()}\${index}\`);
console.log(indexedLetters); // 输出: ['A0', 'B1', 'C2']
- 在 React 中渲染列表
function App() {
const items = ['Apple', 'Banana', 'Orange'];
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
5. 链式调用
const numbers = [1, 2, 3, 4, 5];
const result = numbers
.map(num => num * 2)
.filter(num => num > 5)
.reduce((acc, num) => acc + num, 0);
console.log(result); // 输出: 21
注意事项
map()不会修改原数组。它创建一个新数组,不会对原数组产生副作用。map()对数组中的每个元素都会调用一次提供的函数。- 如果原数组中包含未定义的元素,
map()在迭代时会跳过它们,但新数组中仍会保留这些位置,值为undefined。 - 当你不需要返回值,只想遍历数组执行某些操作时,应该使用
forEach()而不是map()。 map()常常与其他数组方法(如filter()和reduce())一起使用,形成强大的数据处理管道。- 在处理大型数组时,考虑使用
for循环来优化性能,因为map()会创建一个新数组。
下面是高级用法:
- reduce() - 对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 输出: 15
- some() - 测试数组中是不是至少有1个元素通过了被提供的函数测试
const numbers = [1, 2, 3, 4, 5];
const hasEvenNumber = numbers.some(num => num % 2 === 0);
console.log(hasEvenNumber); // 输出: true
- every() - 测试一个数组内的所有元素是否都能通过某个指定函数的测试
const numbers = [1, 2, 3, 4, 5];
const allPositive = numbers.every(num => num > 0);
console.log(allPositive); // 输出: true
- find() - 返回数组中满足提供的测试函数的第一个元素的值
const numbers = [1, 2, 3, 4, 5];
const firstEven = numbers.find(num => num % 2 === 0);
console.log(firstEven); // 输出: 2
- findIndex() - 返回数组中满足提供的测试函数的第一个元素的索引
const fruits = ['apple', 'banana', 'orange', 'grape'];
const index = fruits.findIndex(fruit => fruit === 'orange');
console.log(index); // 输出: 2
- includes() - 判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false
const fruits = ['apple', 'banana', 'orange'];
console.log(fruits.includes('banana')); // 输出: true
console.log(fruits.includes('grape')); // 输出: false
- flat() - 按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回
const arr = [1, 2, [3, 4, [5, 6]]];
console.log(arr.flat(2)); // 输出: [1, 2, 3, 4, 5, 6]
- flatMap() - 首先使用映射函数映射每个元素,然后将结果压缩成一个新数组
const arr = [1, 2, 3, 4];
const result = arr.flatMap(x => [x, x * 2]);
console.log(result); // 输出: [1, 2, 2, 4, 3, 6, 4, 8]
- from() - 从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
const set = new Set(['foo', 'bar', 'baz', 'foo']);
const arr = Array.from(set);
console.log(arr); // 输出: ["foo", "bar", "baz"]