JS 添加/移除数组元素
在 JavaScript 中,数组提供了多种方法来添加或移除元素。这些方法包括 push
、pop
、shift
和 unshift
,它们可以用来操作数组的尾端和首端的元素。
添加元素
arr.push(...items)
: 在数组的尾端添加一个或多个元素。arr.unshift(...items)
: 在数组的首端添加一个或多个元素。
移除元素
arr.pop()
: 移除数组尾端的最后一个元素并返回它。arr.shift()
: 移除数组首端的第一个元素并返回它。
使用展开运算符
展开运算符 ...
可以用来将一个数组的所有元素添加到另一个数组中。
示例代码
// 初始化数组
let arr = ["Apple", "Banana"];
// 使用 push() 添加元素到数组尾端
arr.push("Orange", "Peach");
console.log(arr); // ["Apple", "Banana", "Orange", "Peach"]
// 使用 pop() 从数组尾端移除元素
let last = arr.pop();
console.log(last); // "Peach"
console.log(arr); // ["Apple", "Banana", "Orange"]
// 使用 shift() 从数组首端移除元素
let first = arr.shift();
console.log(first); // "Apple"
console.log(arr); // ["Banana", "Orange"]
// 使用 unshift() 添加元素到数组首端
arr.unshift("Strawberry", "Lemon");
console.log(arr); // ["Strawberry", "Lemon", "Banana", "Orange"]
// 使用展开运算符合并数组
let fruits = ["Apple", "Banana"];
let moreFruits = ["Orange", "Peach"];
fruits.push(...moreFruits);
console.log(fruits); // ["Apple", "Banana", "Orange", "Peach"]
let berries = ["Strawberry", "Blueberry"];
fruits.unshift(...berries);
console.log(fruits); // ["Strawberry", "Blueberry", "Apple", "Banana", "Orange", "Peach"]
JS 中使用splice
修改数组
JavaScript 数组的splice
方法可以用来添加、删除或替换数组中的元素,使用方式非常灵活。
删除数组元素
使用 splice(start, deleteCount)
可以从索引 start
删除 deleteCount
个元素。
let arr = ["I", "study", "JavaScript"];
arr.splice(1, 1); // 从索引 1 删除 1 个元素
console.log(arr); // 输出: ["I", "JavaScript"]
替换数组元素
splice(start, deleteCount, ...items)
从索引 start
删除 deleteCount
个元素,并插入 ...items
。
let arr = ["I", "study", "JavaScript", "right", "now"];
arr.splice(0, 3, "Let's", "dance"); // 删除前三个元素,添加两个新元素
console.log(arr); // 输出: ["Let's", "dance", "right", "now"]
插入元素
将 deleteCount
设置为 0
,splice()
可以在不删除任何元素的情况下插入新元素。
let arr = ["I", "study", "JavaScript"];
arr.splice(2, 0, "complex", "language"); // 从索引 2 开始插入元素
console.log(arr); // 输出: ["I", "study", "complex", "language", "JavaScript"]
使用负索引
splice()
允许使用负索引,从数组末尾开始计算位置。
let arr = [1, 2, 5];
arr.splice(-1, 0, 3, 4); // 从数组末尾前一位开始插入元素
console.log(arr); // 输出: [1, 2, 3, 4, 5]
JS 中使用slice
提取数组的子集或者创建数组的副本
使用数组的 slice()
方法可以方便地在不修改原数组的情况下,提取数组的子集或者创建数组的副本。这在编程中非常有用,特别是当你需要保留原数组不变,同时又需要操作数组的一部分时。
基本用法
arr.slice([start], [end])
从索引 start
到 end
(不包括 end
)复制元素到一个新数组。
start
和 end
参数都可以是负数,表示从数组末尾开始计算。
创建数组副本
调用 arr.slice()
不带任何参数将创建原数组的一个浅副本。
示例代码
let arr = ["t", "e", "s", "t"];
// 复制从位置 1 到位置 3 的元素
console.log(arr.slice(1, 3)); // 输出: ["e", "s"]
// 复制从位置 -2 到尾端的元素
console.log(arr.slice(-2)); // 输出: ["s", "t"]
// 创建数组的副本
let arrCopy = arr.slice();
console.log(arrCopy); // 输出: ["t", "e", "s", "t"]
JS 中使用 concat 方法合并数组
arr.concat()
是 JavaScript 中用于合并数组的方法,它创建一个新数组,包含原数组 arr
和作为参数传递的数组或值。
arr.concat(arg1, arg2, ...)
可以接受任意数量的参数,无论是数组还是单独的值。
如果参数是数组,它会将数组中的元素复制到新数组中。
如果参数不是数组,它会直接将参数复制到新数组中。
concat()
不会改变现有的数组,而是返回一个新数组。
// 初始化数组
let arr = [1, 2];
// 使用 concat() 合并数组
console.log(arr.concat([3, 4])); // 输出: [1, 2, 3, 4]
console.log(arr.concat([3, 4], [5, 6])); // 输出: [1, 2, 3, 4, 5, 6]
console.log(arr.concat([3, 4], 5, 6)); // 输出: [1, 2, 3, 4, 5, 6]
concat 类数组对象(具有索引和 length
属性的对象)时,通常是将其作为单个元素被添加。如果类数组对象有 Symbol.isConcatSpreadable
属性,并且其值为 true
,则其元素会被 concat()
当作数组处理并被添加到新数组中。
// 初始化数组
let arr = [1, 2];
let arrayLike = { 0: "something", length: 1 };
console.log(arr.concat(arrayLike)); // 输出: [1, 2, arrayLike]
// 类数组对象具有 Symbol.isConcatSpreadable 属性
let arrayLikeWithSpreadable = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2,
};
console.log(arr.concat(arrayLikeWithSpreadable)); // 输出: [1, 2, "something", "else"]
JS 中使用 arr.forEach 遍历数组
当我们需要遍历一个数组时 —— 我们可以使用 forEach
,for
或 for..of
。
数组方法 forEach 遍历数组
arr.forEach(function(item, index, array) {...})
允许你为数组 arr
中的每个元素 item
执行一个函数。
函数可以接受三个参数:当前元素 item
,当前元素的索引 index
,以及被遍历的数组 array
。
// 定义一个数组
let characters = ["Bilbo", "Gandalf", "Nazgul"];
// 使用 forEach() 显示数组的每个元素
characters.forEach(alert);
// 使用 forEach() 更详细地显示每个元素及其索引
characters.forEach((item, index, array) => {
console.log(`${item} is at index ${index} in ${array}`);
});
for 循环遍历数组
for
循环:
let arr = ["Apple", "Orange", "Pear"];
for (let i = 0; i < arr.length; i++) {
alert(arr[i]);
}
for..of
循环:
let fruits = ["Apple", "Orange", "Plum"];
for (let fruit of fruits) {
alert(fruit);
}
JS 数组中搜索特定的元素或对象
indexOf
和 lastIndexOf
arr.indexOf(item, from)
用于查找 item
从索引 from
开始的第一个出现的位置。如果找不到,返回 -1
。
arr.lastIndexOf(item, from)
类似于 indexOf
,但它从数组的末尾开始向前搜索。
// 初始化数组
let fruits = ["Apple", "Orange", "Apple"];
// 使用 indexOf 和 lastIndexOf
console.log(fruits.indexOf("Apple")); // 0
console.log(fruits.lastIndexOf("Apple")); // 2
includes
arr.includes(item, from)
用于检查数组中是否包含 item
,从索引 from
开始搜索。如果找到,返回 true
;否则,返回 false
。
includes
方法可以正确处理 NaN
值,这是 indexOf
无法做到的。
// 初始化数组
let arr = [1, 0, false];
console.log(arr.includes(1)); // true
const arr = [NaN];
alert(arr.indexOf(NaN)); // -1(错,应该为 0)
alert(arr.includes(NaN)); // true(正确)
find
和 findIndex
/findLastIndex
arr.find(callback)
用于找到第一个满足 callback
函数条件的元素。如果没有找到符合条件的元素,返回 undefined
。
arr.findIndex(callback)
类似于 find
,但返回满足条件的元素的索引,如果没有找到,则返回 -1
。
arr.findLastIndex(callback)
类似于 findIndex
,但它从数组的末尾开始向前搜索。
// 使用 find 和 findIndex
let users = [
{ id: 1, name: "John" },
{ id: 2, name: "Pete" },
{ id: 3, name: "Mary" },
];
let user = users.find((item) => item.id == 1);
console.log(user.name); // John
console.log(users.findIndex((user) => user.name == "John")); // 0
// 使用 findLastIndex
let usersWithDuplicate = [
{ id: 1, name: "John" },
{ id: 2, name: "Pete" },
{ id: 3, name: "Mary" },
{ id: 4, name: "John" },
];
console.log(usersWithDuplicate.findLastIndex((user) => user.name == "John")); // 3
filter
arr.filter(callback)
方法创建一个新数组,其中包含所有通过由 callback
函数实现的测试的元素。
callback
函数接受三个参数:当前元素 item
,当前元素的索引 index
,以及数组本身 array
。
如果 callback
函数返回 true
,当前元素 item
会被添加到新数组中。如果没有元素通过测试(即 callback
函数总是返回 false
),则返回一个空数组。
// 初始化用户数组
let users = [
{ id: 1, name: "John" },
{ id: 2, name: "Pete" },
{ id: 3, name: "Mary" },
];
// 使用 filter() 方法找到 id 小于 3 的用户
let someUsers = users.filter((item) => item.id < 3);
console.log(someUsers.length); // 输出: 2
console.log(someUsers); // 输出: [{id: 1, name: "John"}, {id: 2, name: "Pete"}]
JS 数组转换
map
当我们需要遍历数组并返回每个元素的数据时 —— 我们可以使用 map。
arr.map(callback)
创建一个新数组,其中包含对原数组中每个元素调用 callback
函数的结果。
callback
函数接受三个参数:当前元素 item
,当前元素的索引 index
,以及数组本身 array
。
// 使用 map 方法
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map((item) => item.length);
console.log(lengths); // [5, 7, 6]
sort(fn)
arr.sort(compareFunction)
对数组进行原位排序,改变原数组的元素顺序。
如果没有提供 compareFunction
,元素默认按字符串 Unicode 码点进行排序。使用 localeCompare
可以根据本地语言环境的特定顺序来排序字符串。
// 使用 sort 方法排序字符串
let countries = ["Österreich", "Andorra", "Vietnam"];
countries.sort((a, b) => (a > b ? 1 : -1));
console.log(countries); // ['Andorra', 'Vietnam', 'Österreich'](错的)
countries.sort((a, b) => a.localeCompare(b));
console.log(countries); // ['Andorra', 'Österreich', 'Vietnam'](对的!)
为了按数字大小排序,需要提供一个 compareFunction
,比较函数只需要返回一个正数表示“大于”,一个负数表示“小于”。
// 使用 sort 方法排序数字
let numbers = [1, 2, 15];
numbers.sort();
console.log(numbers); // [1, 15, 2]
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 2, 15]
reverse
数组倒序:
let arr = [1, 2, 3, 4, 5];
arr.reverse();
alert(arr); // 5,4,3,2,1
split/join
在 JavaScript 中,split
和 join
方法是处理字符串和数组的有用工具。split
方法可以将一个字符串分割成数组,而 join
方法则可以将数组元素合并成一个字符串。
split 方法
let names = "John, Pete, Mary";
let nameArray = names.split(", ");
// nameArray 现在是 ['John', 'Pete', 'Mary']
还可以限制结果数组的长度,通过提供一个可选的第二个参数给 split
方法。
let names = "Bilbo, Gandalf, Nazgul, Saruman";
let limitedArray = names.split(", ", 2);
// limitedArray 现在是 ['Bilbo', 'Gandalf']
调用带有空参数的 split,会将字符串拆分为字母数组:
let str = "test";
alert(str.split("")); // t,e,s,t
join 方法
与 split
相反,join
方法会取一个数组并将其元素连接成一个字符串。元素之间的连接符由 join
方法的参数指定。
let nameArray = ["Bilbo", "Gandalf", "Nazgul"];
let names = nameArray.join("; ");
// names 现在是 'Bilbo; Gandalf; Nazgul'
reduce/reduceRight
在 JavaScript 中,reduce
和 reduceRight
是数组方法,用于将数组中的所有元素归纳为单个值。这些方法通常用于累加数值或结合数组中的元素。
reduce
方法接受一个回调函数和一个可选的初始值作为参数。
let value = arr.reduce(
function (accumulator, item, index, array) {
// ...
},
[initial]
);
回调函数被执行时,它会接收四个参数:累加器(accumulator)、当前元素(item)、当前索引(index)和数组本身(array)。传递给 reduce 的函数仅使用了 2 个参数,通常这就足够了。
accumulator 是上一次回调返回的值,对于第一次调用,它是初始值(如果提供了的话)。
let arr = [1, 2, 3, 4, 5];
// 使用 reduce 来计算数组的总和
let sum = arr.reduce((accumulator, current) => accumulator + current, 0);
alert(sum); // 输出 15
如果没有提供初始值,reduce
会使用数组的第一个元素作为初始值,并从第二个元素开始处理。
reduceRight
方法的工作原理与 reduce
相同,但它从数组的末尾开始向前工作,而不是从头开始。
Array.isArray 检测一个值是否为数组
在 JavaScript 中,由于数组是特殊类型的对象,我们不能仅仅通过 typeof
操作符来区分数组和普通对象。
alert(typeof {}); // object
alert(typeof []); // object(相同)
为了解决这个问题,JavaScript 提供了 Array.isArray()
方法,它可以准确地检测一个值是否为数组。
// 检测普通对象
console.log(Array.isArray({})); // 输出 false
// 检测数组
console.log(Array.isArray([])); // 输出 true