一.数组的定义
在 JavaScript 中,数组是一种用于存储一系列值的高级全局对象。数组可以包含任意类型的值,例如数字、字符串、对象或甚至其他数组。数组中的元素可以通过其索引(基于零的整数)来访问和修改。
数组的定义通常有两种方式:
- 字面量语法:使用方括号
[]
来创建一个新数组。例如:let myArray = [1,2,3];
- 构造函数语法:使用
new Array()
来创建一个新数组。例如:let myArray = new Array(1, 2, 3); (一般不使用)
JavaScript 数组是动态的,意味着它们可以在运行时动态地增长或缩减大小。数组还拥有一系列内建的方法来进行元素的遍历、搜索、排序和变换。这些方法使得数组在 JavaScript 中成为处理数据集合的一个非常强大和灵活的工具。
二.数组解构详解
1.基本使用
let [a, b] = [1, 2];
console.log(a); // 输出:1
console.log(b); // 输出:2
2.默认值
let [a, b, c = 3] = [1, 2];
console.log(a); // 输出:1
console.log(b); // 输出:2
console.log(c); // 输出:3
3.跳过元素
let [a, , b] = [1, 2, 3];
console.log(a); // 输出:1
console.log(b); // 输出:3
4.剩余元素
let [a, ...rest] = [1, 2, 3, 4];
console.log(a); // 输出:1
console.log(rest); // 输出:[2, 3, 4]
5.嵌套解构
let [a, [b, c]] = [1, [2, 3]];
console.log(a); // 输出:1
console.log(b); // 输出:2
console.log(c); // 输出:3
6.函数参数中的数组解构
function sum([a, b]) {
return a + b;
}
console.log(sum([1, 2])); // 输出:3
三.数组扩展运算符
1.函数调用
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 输出:6
2.构造数组
当你需要构建新数组时,扩展运算符可以用来合并多个数组或插入额外的元素:
const part1 = [1, 2];
const part2 = [3, 4];
const combined = [...part1, ...part2];
console.log(combined); // 输出:[1, 2, 3, 4]
const extended = [0, ...part1, 3, ...part2, 5];
console.log(extended); // 输出:[0, 1, 2, 3, 3, 4, 5]
3.复制数组
const original = [1, 2, 3];
const copy = [...original];
console.log(copy); // 输出:[1, 2, 3]
4. 转换类数组对象或可迭代对象
扩展运算符可以将类数组对象(如 arguments
或 NodeList
)或可迭代对象(如 Set
或 Map
的键或值)转换为真正的数组:
function toArray() {
return [...arguments];
}
console.log(toArray(1, 2, 3)); // 输出:[1, 2, 3]
const set = new Set([1, 2, 3]);
const setToArray = [...set];
console.log(setToArray); // 输出:[1, 2, 3]
5. 字符串到数组的转换
const greeting = "Hello";
const chars = [...greeting];
console.log(chars); // 输出:['H', 'e', 'l', 'l', 'o']
三.数组常用方法
>> Array.from
Array.from()
方法创建一个新的、浅复制的数组实例,从一个类似数组或可迭代对象中创建一个新的数组实例.
Array.from(arrayLike, mapFn, thisArg)
- arrayLike: 想要转换成数组的类数组对象或可迭代对象。
- mapFn (可选): 如果指定了该参数,新数组中的每个元素会执行该回调函数。
- thisArg (可选): 执行回调函数
mapFn
时this
对象
>>示例:
// 从类数组对象创建数组
console.log(Array.from(1,2,3)); // 输出: [1, 2, 3]
// 从 Set 创建数组
const s = new Set(["foo", "bar", "baz", "foo"]);
const arr = Array.from(s);
console.log(arr); // 输出: ["foo", "bar", "baz"]
// 使用 map 函数
const arr2 = Array.from([1, 2, 3], x => x + x);
console.log(arr2); // 输出: [2, 4, 6]
const arrayLike = {"0": "1", "1": "2", "2": "3", length: 3}; // 类数组对象
// 自定义上下文对象
const multiplier = {
factor: 2,
multiplyByFactor(value) {
return value * this.factor;
}
};
// 使用Array.from()转换并应用map函数,同时指定thisArg
const newArray = Array.from(arrayLike, function(item) {
return this.multiplyByFactor(Number(item));
}, multiplier);
console.log(newArray); // 输出: [2, 4, 6]
>>注意:
我们平时的使用场景一般不会那么复杂,一般是将HTMLCollection或者是NodeList
转化成数组对象,例如:
var table = document.getElementById('table')
var rows = Array.from(table.getElementsByTagName('tr')) // 将HTMLCollection转换为数组
var heads = Array.from(table.getElementsByTagName('th'))
>> Array.of
创建一个具有可变数量参数的新数组实例,无论参数的数量或类型如何 .
Array.of(element0, element1, ..., elementN)
>> Array.prototype.find()
find
方法用于查找数组中满足提供的测试函数的第一个元素的值。如果没有找到满足条件的元素,则返回 undefined
。
arr.find(callback(element[, index[, array]])[, thisArg])
- callback: 用于测试数组中的每个元素的函数。返回
true
表示找到了符合条件的元素,find
方法将立即返回该元素的值。- element: 数组中正在处理的当前元素。
- index (可选): 数组中正在处理的当前元素的索引。
- array (可选): 调用
find
方法的数组。- thisArg (可选): 执行回调时使用的
this
值。
常用用法(简单的环境下):
const people = [
{ name: 'John', age: 16 },
{ name: 'Jane', age: 20 },
{ name: 'Jim', age: 15 }
];
const adult = people.find(person => person.age > 18);
console.log(adult); // 输出: { name: 'Jane', age: 20 }
罕见用法(参数拉满):
const numbers = [1, 3, 5, 8, 10, 12];
// 上下文对象
const checker = {
isEven: function(number) {
return number % 2 === 0;
}
};
// 回调函数
function callback(element, index, array) {
console.log('Current Element:', element);
console.log('Current Index:', index);
console.log('Array:', array);
// 使用上下文对象中的方法来判断当前元素是否为偶数
return this.isEven(element);
}
// 使用 find 方法,包括 thisArg 参数
const firstEven = numbers.find(callback, checker);
console.log('First even number:', firstEven);
>> Array.prototype.fill()
arr.fill(value[, start[, end]])
- value: 要填充数组的值。
- start (可选): 开始填充的起始索引,默认为0。
- end (可选): 停止填充的结束索引(不包括此索引),默认为
arr.length
。
const array1 = [1, 2, 3, 4, 5];
console.log(array1.fill(0)); // 输出: [0, 0, 0, 0, 0]
const array2 = [1, 2, 3, 4, 5];
console.log(array2.fill(0, 2)); // 输出: [1, 2, 0, 0, 0]
const array3 = [1, 2, 3, 4, 5];
console.log(array3.fill(0, -3)); // 输出: [1, 2, 0, 0, 0]
>> Array.prototype.flat()
flat()
方法用于将嵌套的数组“拍平”成一维数组。它可以按照指定的深度递归遍历数组,并将所有元素与其子数组中的元素合并为一个新数组。
const newArray = arr.flat(depth);
depth (可选): 指定要提取嵌套数组的深度,默认为1。
const nestedArray = [1, [2, [3, [4]]]];
const flatArray1 = nestedArray.flat();
console.log(flatArray1); // 输出: [1, 2, [3, [4]]]
const flatArray2 = nestedArray.flat(2);
console.log(flatArray2); // 输出: [1, 2, 3, [4]]
const flatArray3 = nestedArray.flat(Infinity);
console.log(flatArray3); // 输出: [1, 2, 3, 4]
>>Array.prototype.flatMap()
flatMap()
方法首先使用映射函数映射每个元素,然后将结果数组拍平一个层级。它相当于先执行 map()
方法,然后对 map()
方法的结果执行 flat()
方法,但 flatMap()
只能将数组拍平一层。
const newArray = arr.flatMap(callback(currentValue[, index[, array]])[, thisArg]);
- callback: 生成新数组元素的函数,可以接受三个参数:当前元素 (
currentValue
)、当前元素的索引 (index
)、原数组 (array
)。- thisArg (可选): 执行
callback
函数时使用的this
值。
const array = [1, 2, 3, 4];
const mappedAndFlattened = array.flatMap(x => [x, x * 2]);
console.log(mappedAndFlattened); // 输出: [1, 2, 2, 4, 3, 6, 4, 8]
>>.
Array.prototype.push()
向数组末尾添加一个或多个元素,并返回新的长度。
let array = [1, 2];
array.push(3); // array 现在是 [1, 2, 3]
>>.
Array.prototype.pop()
移除数组的最后一个元素,并返回该元素。
let lastElement = array.pop(); // 返回 3,array 现在是 [1, 2]
>>.Array.prototype.shift()
移除数组的第一个元素,并返回该元素。
let firstElement = array.shift(); // 返回 1,array 现在是 [2]
>>.Array.prototype.unshift()
向数组开头添加一个或多个元素,并返回新的长度。
>>.Array.prototype.slice()
返回数组的一个部分(浅复制)。
这一对象是一个由 start
和 end
决定的原数组的浅拷贝(包括 start
,不包括 end
),其中 start
和 end
代表了数组元素的索引。原始数组不会被改变。
没有参数的情况下默认将数组全部拷贝
let newArray = array.slice(1); // 返回 [2]
>>.
Array.prototype.splice()
添加/删除数组中的元素。
array.splice(1, 0, 'a', 'b'); // 从索引 1 开始,删除 0 个元素,添加 'a' 和 'b'
>>.Array.prototype.forEach()
调用数组的每个元素,并将元素传递给回调函数(只遍历不返回值)
array.forEach((element, index) => { console.log(element, index); // 打印每个元素及其索引 });
>>.Array.prototype.map()
创建一个新数组,其结果是该数组中的每个元素调用一次提供的函数后的返回值。
let doubled = array.map(x => x * 2); // 对每个元素乘以 2
>>.Array.prototype.filter()
创建一个新数组,包含通过所提供函数实现的测试的所有元素。
let even = array.filter(x => x % 2 === 0); // 过滤出偶数元素
>>.Array.prototype.reduce()
对数组中的每个元素执行一个由您提供的 reduce 函数(从左到右),将其结果汇总为单个返回值。
let sum = array.reduce((accumulator, currentValue) => accumulator + currentValue, 0); // 计算数组元素的和
reduce 函数:这个函数接受四个参数:
a. accumulator
(累加器):累加器累计回调的返回值;它是上一次调用回调时返回的累积值,或者是提供的初始值(initialValue).
b. array
(可选):调用 reduce()
的数组。currentIndex
(可选):数组中正在处理的当前元素的索引。如果提供了初始值,则起始索引号为 0
,否则为 1
。
c.currentValue
(当前值):数组中正在处理的元素。
d.初始值(initialValue
)(可选):作为第一次调用 callback
函数时的第一个参数的值。如果没有提供初始值,则将使用数组的第一个元素。(就是上面例子中的0)
在 reduce()
的作用过程中,accumulator
和 currentValue
是必须的参数,currentIndex
和 array
是可选的。如果没有提供 initialValue
,reduce()
会从数组的第二个元素开始执行,将第一个元素作为初始的 accumulator
值。
>>.Array.prototype.join()
用于将数组中的所有元素连接成一个字符串。您可以指定一个可选的字符串作为分隔符,来分隔数组中的每个元素。如果没有提供分隔符,则默认使用逗号(,
)。
let elements = ['Fire', 'Air', 'Water'];
let result = elements.join(); // 默认使用逗号,结果为 "Fire,Air,Water"
let resultWithSpace = elements.join(' '); // 使用空格分隔,结果为 "Fire Air Water"
let resultWithDash = elements.join('-'); // 使用破折号分隔,结果为 "Fire-Air-Water"