Array

Array 对象

Array 里有什么

1
2
3
console.log(Object.getOwnPropertyNames(Array))
console.log(Object.getOwnPropertyNames(Array.prototype))
console.log(Object.getOwnPropertyNames(new Array()))
1
2
3
(7) ['length', 'name', 'prototype', 'isArray', 'from', 'fromAsync', 'of']
(40) ['length', 'constructor', 'at', 'concat', 'copyWithin', 'fill', 'find', 'findIndex', 'findLast', 'findLastIndex', 'lastIndexOf', 'pop', 'push', 'reverse', 'shift', 'unshift', 'slice', 'sort', 'splice', 'includes', 'indexOf', 'join', 'keys', 'entries', 'values', 'forEach', 'filter', 'flat', 'flatMap', 'map', 'every', 'some', 'reduce', 'reduceRight', 'toReversed', 'toSorted', 'toSpliced', 'with', 'toLocaleString', 'toString']
['length']

!Array.png

数组元素添加和删除 5

  • push
  • pop
  • unshift
  • shift
  • splice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = [1,2,3];
console.log(a.__proto__ === Array.prototype);
console.log(a.constructor === Array);
var b = [13,14,15]
// 数组元素添加和删除 5个
a.push(4,5,6) //[1, 2, 3, 4, 5, 6]
var newLength = a.push(...b)// [1, 2, 3, 4, 5, 6, 13, 14, 15],9
var items = a.pop() // [1, 2, 3, 4, 5, 6, 13, 14],15
a.unshift(7,8,9)// [7, 8, 9, 1, 2, 3, 4, 5, 6, 13, 14]
a.shift()// [8, 9, 1, 2, 3, 4, 5, 6, 13, 14]
console.log(a);
//定位删除添加
//`array.splice(start, deleteCount, item1, item2, ...)`
let arr = [1, 2, 3, 4, 5];
arr.splice(2, 1); // 从索引 2 开始删除 1 个元素,arr 现在是 [1, 2, 4, 5]
arr.splice(2, 0, 'a', 'b'); // 从索引 2 开始添加 'a' 和 'b',arr 现在是 [1, 2, 'a', 'b', 4, 5]

数组元素查找 5

  • indexOf 查找数组中第一个与给定元素相等的元素的索引,如果不存在则返回-1
  • lastIndexOf 查找数组中最后一个与给定元素相等的元素的索引,如果不存在则返回-1
  • find 查找数组中第一个满足提供的测试函数的元素的值,如果没有找到则返回undefined
  • findIndex 查找数组中第一个满足提供的测试函数的元素的索引,如果没有找到则返回-1
  • findLastIndex
1
2
3
4
5
let arr = [1, 2, 3, 4, 2];
let index = arr.indexOf(3); // 2
let index2 = arr.lastIndexOf(2); // 4
let result = arr.find(element => element > 2); // 3
let result2 = arr.findIndex(element => element > 2); // 2

遍历数组 5

  • forEach对数组中的每个元素执行一次给定的函数
  • map创建一个新数组,其元素是调用一次提供的函数后的返回值
  • filter创建一个新数组,包含通过所提供函数实现的测试的所有元素
  • reduce对数组中的所有元素执行一个由左到右的归并操作,将其归并为单个返回值
  • reduceRight对数组中的所有元素执行一个由右到左的归并操作,将其归并为单个返回值
1
2
3
4
5
6
let arr = [1, 2, 3, 4, 5];
arr.forEach(element => console.log(element));// 1 2 3 4 5
let mapArr = arr.map(element => element * element); // [1, 4, 9, 16, 25]
let evenNumbers = arr.filter(element => element % 2 === 0); // [2, 4]
let sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0); //15
let sumRight = arr.reduceRight((accumulator, currentValue) => accumulator + currentValue, 0); // 15

排序 2

  • sort 对数组的元素进行原地排序,并返回数组
    • 返回一个小于 0 的值,则 a 会被排序到 b 之前
    • 返回一个大于 0 的值,则 a 会被排序到 b 之后
  • reverse对数组的元素进行原地反转,并返回数组
1
2
3
4
5
6
7
8
9
10
let arr = [3, 1, 4, 1, 5, 9, 2, 6];
arr.sort((a, b) => {
return a - b
});
console.log(arr);//[1, 1, 2, 3, 4, 5, 6, 9]
arr.sort((a, b) => {
return b - a
});
console.log(arr);//[9, 6, 5, 4, 3, 2, 1, 1]
console.log(arr.reverse());//[1, 1, 2, 3, 4, 5, 6, 9]

拷贝合并 2

  • slice() - 创建一个新数组,包含从开始到结束(不包括结束)的数组中的元素
  • concat() - 创建一个新数组,包含原数组和一个或多个其他数组或值的组合
1
2
3
4
5
let arr = [1, 2, 3, 4, 5];
let subArray = arr.slice(1, 3); // subArray 是 [2, 3]
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let newArr = arr1.concat(arr2); // newArr 是 [1, 2, 3, 4, 5, 6]

其他 6

  • join 将数组的所有元素连接成一个字符串,并返回这个字符串
  • includes 检查数组是否包含某个值,如果是则返回 true,否则返回 false
  • every 测试数组中的所有元素是否都通过了提供的函数测试,如果是则返回 true,否则返回 false
  • some 测试数组中的至少一个元素是否通过了提供的函数测试,如果是则返回 true,否则返回 false
  • fill 用一个固定值填充数组的从起始索引到终止索引内的元素
  • copyWithin 浅复制

常规 4

  • toString
  • toLocaleString
  • constructor
  • length

Js里有没有不改变原数组的排序方法

在JavaScript中,如果你想要对数组进行排序而不改变原数组,可以使用以下几种方法:

  1. 使用slice()方法
    slice()方法可以返回一个新的数组对象,这个对象是一个由 beginend(不包括 end)的原数组的浅拷贝。然后你可以对新数组使用 sort() 方法进行排序。
    1
    2
    3
    const arr = [3, 1, 4, 1, 5, 9];
    const sortedArr = arr.slice().sort((a, b) => a - b);
    // sortedArr 现在是 [1, 1, 3, 4, 5, 9],而 arr 保持不变
  2. 使用Array.from()方法
    Array.from()方法创建一个新数组实例,然后你可以对这个新数组进行排序。
    1
    2
    3
    const arr = [3, 1, 4, 1, 5, 9];
    const sortedArr = Array.from(arr).sort((a, b) => a - b);
    // sortedArr 现在是 [1, 1, 3, 4, 5, 9],而 arr 保持不变
  3. 使用扩展运算符(Spread Operator)
    扩展运算符...可以用来复制数组中的元素到一个新数组中,然后对这个新数组进行排序。
    1
    2
    3
    const arr = [3, 1, 4, 1, 5, 9];
    const sortedArr = [...arr].sort((a, b) => a - b);
    // sortedArr 现在是 [1, 1, 3, 4, 5, 9],而 arr 保持不变
  4. 使用map()方法
    如果你需要对数组中的每个元素进行某种操作后再排序,可以使用map()方法创建一个新数组,然后排序。
    1
    2
    3
    const arr = [3, 1, 4, 1, 5, 9];
    const sortedArr = arr.map(a => a * 1).sort((a, b) => a - b);
    // sortedArr 现在是 [1, 1, 3, 4, 5, 9],而 arr 保持不变
    以上方法都可以在不改变原数组的情况下对数组进行排序。选择哪一种方法取决于你的具体需求和代码风格。

DS

JavaScript 的 Array(数组)是一种用于存储有序数据集合的对象,支持多种数据类型元素,并提供丰富的内置方法用于操作数据。以下是 JavaScript 数组的详细介绍:

1. 数组的创建

1.1 字面量形式

1
2
const arr1 = [];          // 空数组
const arr2 = [1, "a", {}]; // 包含不同数据类型的元素

1.2 构造函数

1
2
3
const arr3 = new Array();         // 空数组
const arr4 = new Array(5); // 长度为5的空数组(稀疏数组)
const arr5 = new Array(1, 2, 3); // 等同于 [1, 2, 3]

2. 基本特性

  • 动态长度:数组的 length 属性会自动调整。
    1
    2
    3
    const arr = [1, 2];
    arr.length = 5; // 变为 [1, 2, empty × 3]
    arr.length = 1; // 截断为 [1]
  • 稀疏数组:数组可以有“空位”(empty),如 [1, , 3]。某些方法会跳过空位。
  • 类型灵活:可存储任意数据类型(包括其他数组或对象)。

3. 常用方法

3.1 增删元素

方法 描述 是否修改原数组
push() 末尾添加元素,返回新长度 ✔️
pop() 移除并返回最后一个元素 ✔️
unshift() 开头添加元素,返回新长度 ✔️
shift() 移除并返回第一个元素 ✔️
splice() 添加/删除任意位置的元素 ✔️
示例
1
2
3
const arr = [1, 2];
arr.push(3); // [1, 2, 3]
arr.splice(1, 1); // 删除索引1的元素 → [1, 3]

3.2 遍历与转换

方法 描述 返回值
forEach() 遍历数组,无返回值 undefined
map() 对每个元素执行函数,返回新数组 新数组
filter() 返回符合条件元素的新数组 新数组
reduce() 累积计算结果(如求和) 单个值
join() 将数组转为字符串(默认逗号分隔) 字符串
示例
1
2
3
[1, 2, 3].map(x => x * 2);          // [2, 4, 6]
[1, 2, 3].filter(x => x > 1); // [2, 3]
[1, 2, 3].reduce((sum, x) => sum + x, 0); // 6

3.3 查找与判断

方法 描述
indexOf() 返回元素首次出现的索引(无则返回-1)
includes() 判断是否包含某元素(支持 NaN
find() 返回第一个符合条件的元素(无则返回undefined
some()/every() 检查是否有/所有元素满足条件
示例
1
2
[1, 2, NaN].includes(NaN);    // true
[1, 2, 3].find(x => x > 1); // 2

3.4 排序与反转

方法 描述 是否修改原数组
sort() 排序(默认按字符串Unicode) ✔️
reverse() 反转数组顺序 ✔️
示例
1
[3, 1, 2].sort((a, b) => a - b);  // [1, 2, 3]

4. 高级操作

4.1 展开运算符 (...)

合并数组或展开元素:

1
2
const arr1 = [1, 2];
const arr2 = [...arr1, 3]; // [1, 2, 3]

4.2 扁平化数组

  • flat():扁平化嵌套数组。
  • flatMap():结合 map()flat()
1
2
[1, [2, 3]].flat();         // [1, 2, 3]
[1, 2].flatMap(x => [x, x*2]); // [1, 2, 2, 4]

5. 静态方法

方法 描述
Array.isArray() 判断是否为数组(优于 typeof
Array.from() 将类数组(如 arguments)转为数组
Array.of() 创建包含任意参数的新数组
示例
1
2
3
Array.isArray([]);          // true
Array.from("hello"); // ['h', 'e', 'l', 'l', 'o']
Array.of(5); // [5](与 new Array(5) 不同)

6. 性能与注意点

  • 避免密集操作shift()/unshift() 时间复杂度为 O(n),大数据量时慎用。
  • 稀疏数组:空位可能导致 map() 等方法跳过某些索引。
  • 浅拷贝:方法如 slice() 返回浅拷贝,嵌套对象会共享引用。

总结

JavaScript 数组是灵活且功能强大的数据结构,适合处理有序集合。通过结合高阶函数(如 mapfilter)和 ES6+ 特性(展开运算符、flatMap),可以高效处理复杂数据操作。

数组去重

在 JavaScript 中,有多种方法可以对数组进行去重,以下是几种常见的方法:

1. 使用 Set 对象

Set 对象是一个集合,它只允许存储唯一的值。利用这一特性可以很方便地实现数组去重。

1
2
3
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这种方法简洁高效,是目前最常用的数组去重方式之一,但它会改变原数组的顺序,且不适用于对象数组等复杂数据类型的去重。

2. 使用 filter 方法结合 indexOf

通过 filter 方法遍历数组,利用 indexOf 方法判断当前元素在数组中的第一次出现的位置是否与当前索引相同,如果相同则保留,否则说明是重复元素,不保留。

1
2
3
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item, index) => arr.indexOf(item) === index);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这种方法也不会改变原数组的顺序,但效率相对较低,因为 indexOf 方法会在每次遍历时都对数组进行一次查找。

3. 使用 filter 方法结合 includes

和上面的方法类似,也是通过 filter 方法遍历数组,不过这次是利用 includes 方法判断当前元素是否在数组的前部分(即当前索引之前的部分)出现过,如果出现过则不保留,否则保留。

1
2
3
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.filter((item, index) => !arr.slice(0, index).includes(item));
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这种方法同样不会改变原数组的顺序,但效率也不高,因为每次调用 includes 方法都会对数组的前部分进行遍历。

4. 使用对象或 Map 来记录

创建一个空对象或 Map,遍历数组,将数组中的每个元素作为键(或 Map 的键),值可以是任意值,由于对象或 Map 的键是唯一的,这样就可以实现去重。最后再将对象或 Map 的键转换为数组即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 使用对象
const arr = [1, 2, 2, 3, 4, 4, 5];
const obj = {};
arr.forEach(item => {
obj[item] = true;
});
const uniqueArr = Object.keys(obj).map(item => Number(item)); // 如果数组是数字类型,需要转换回数字
console.log(uniqueArr); // [1, 2, 3, 4, 5]
// 使用 Map
const arr = [1, 2, 2, 3, 4, 4, 5];
const map = new Map();
arr.forEach(item => {
map.set(item, true);
});
const uniqueArr = Array.from(map.keys());
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这种方法效率较高,且可以适用于对象数组等复杂数据类型的去重,但需要额外的转换步骤来获取去重后的数组。

5. 双层循环比较

使用两层循环,外层循环遍历数组的每个元素,内层循环从当前元素的下一个位置开始遍历,比较两个元素是否相等,如果相等则将内层循环中的元素从数组中删除。

1
2
3
4
5
6
7
8
9
10
const arr = [1, 2, 2, 3, 4, 4, 5];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--; // 因为删除了一个元素,所以需要将 j 减 1
}
}
}
console.log(arr); // [1, 2, 3, 4, 5]

这种方法可以原地修改数组,但效率较低,时间复杂度为 O(n^2),且在删除元素时需要注意索引的变化。

6. 使用 reduce 方法

利用 reduce 方法遍历数组,将每个元素依次添加到一个新数组中,添加前先判断新数组中是否已存在该元素,如果不存在则添加,否则不添加。

1
2
3
4
5
6
7
8
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.reduce((acc, current) => {
if (!acc.includes(current)) {
acc.push(current);
}
return acc;
}, []);
console.log(uniqueArr); // [1, 2, 3, 4, 5]

这种方法不会改变原数组的顺序,但效率也不高,因为每次调用 includes 方法都会对新数组进行遍历。

Tips

  • forEach(), filter(), reduce(), every() 和some()都会跳过空位。
  • map()会跳过空位,但会保留这个值
  • js数组和对象相互转化

map 和 filter 的区别

JavaScript 中的 Array.prototype.mapArray.prototype.filter 都是数组的高阶函数,它们都用于遍历数组并对数组中的每个元素执行某种操作,但它们的目的和返回结果有所不同。

map 方法

  • 定义map 方法创建一个新数组,其元素是调用一次提供的函数后的返回值。
  • 语法array.map(function(currentValue, index, arr), thisArg)
    • currentValue:当前正在处理的元素。
    • index(可选):当前正在处理的元素的索引。
    • arr(可选):调用 map 方法的数组。
    • thisArg(可选):执行回调时使用的 this 值。
  • 特点
    • map 方法会遍历数组中的每个元素,并对每个元素执行提供的回调函数。
    • 回调函数的返回值会组成一个新数组,新数组的长度与原数组相同。
    • map 不会改变原数组,它返回的是一个新数组。
    • 如果回调函数中包含异步操作,map 返回的新数组中将包含异步操作的结果,这可能是一个 Promise 数组。
  • 示例
    1
    2
    3
    const numbers = [1, 2, 3, 4];
    const squares = numbers.map(num => num * num);
    console.log(squares); // [1, 4, 9, 16]

filter 方法

  • 定义filter 方法创建一个新数组,包含通过所提供函数实现的测试的所有元素。
  • 语法array.filter(function(currentValue, index, arr), thisArg)
    • 参数与 map 方法相同。
  • 特点
    • filter 方法会遍历数组中的每个元素,并对每个元素执行提供的回调函数。
    • 回调函数应该返回一个布尔值,如果返回 true,则当前元素会被包含在新数组中;如果返回 false,则当前元素不会被包含在新数组中。
    • filter 不会改变原数组,它返回的是一个新数组,新数组的长度可能小于等于原数组的长度。
    • filter 方法可以用于数组的筛选操作,比如筛选出符合条件的元素。
  • 示例
    1
    2
    3
    const numbers = [1, 2, 3, 4, 5];
    const evenNumbers = numbers.filter(num => num % 2 === 0);
    console.log(evenNumbers); // [2, 4]

区别

  • 目的不同
    • map 的目的是对数组中的每个元素进行某种操作,然后返回一个新数组,新数组的元素是操作后的结果。
    • filter 的目的是筛选出数组中符合条件的元素,然后返回一个新数组,新数组的元素是符合条件的原数组中的元素。
  • 返回值不同
    • map 返回的新数组的长度与原数组相同,因为每个元素都会被处理并返回一个结果。
    • filter 返回的新数组的长度可能小于等于原数组的长度,因为只有符合条件的元素才会被包含在新数组中。
  • 回调函数的返回值不同
    • map 的回调函数的返回值会组成新数组的元素。
    • filter 的回调函数的返回值是一个布尔值,用于决定当前元素是否包含在新数组中。

使用场景

  • map
    • 当需要对数组中的每个元素进行某种转换操作时,比如将数组中的每个数字乘以 2、将字符串数组转换为大写等。
    • 当需要基于原数组生成一个新数组,且新数组的元素与原数组的元素一一对应时。
  • filter
    • 当需要从数组中筛选出符合条件的元素时,比如筛选出数组中的偶数、筛选出数组中大于某个值的元素等。
    • 当需要对数组进行条件过滤,生成一个新数组,且新数组的元素是原数组中满足特定条件的元素时。

所有方法

JavaScript 数组提供了许多内置方法,用于操作和处理数组。以下是一些常用的数组方法,按功能分类介绍:

1. 添加和删除元素

push() - 向数组末尾添加一个或多个元素,并返回新长度

1
2
let arr = [1, 2, 3];
arr.push(4); // arr 现在是 [1, 2, 3, 4]

pop() - 删除数组末尾的元素,并返回被删除的元素

1
2
let arr = [1, 2, 3];
let lastElement = arr.pop(); // lastElement 是 3,arr 现在是 [1, 2]

shift() - 删除数组开头的元素,并返回被删除的元素

1
2
let arr = [1, 2, 3];
let firstElement = arr.shift(); // firstElement 是 1,arr 现在是 [2, 3]

unshift() - 向数组开头添加一个或多个元素,并返回新长度

1
2
let arr = [1, 2, 3];
arr.unshift(0); // arr 现在是 [0, 1, 2, 3]

splice() - 从数组中添加或删除元素

  • 删除元素:array.splice(start, deleteCount)
  • 添加元素:array.splice(start, deleteCount, item1, item2, ...)
1
2
3
let arr = [1, 2, 3, 4, 5];
arr.splice(2, 1); // 从索引 2 开始删除 1 个元素,arr 现在是 [1, 2, 4, 5]
arr.splice(2, 0, 'a', 'b'); // 从索引 2 开始添加 'a' 和 'b',arr 现在是 [1, 2, 'a', 'b', 4, 5]

2. 查找元素

indexOf() - 返回数组中第一个匹配元素的索引,如果没有找到则返回 -1

1
2
let arr = [1, 2, 3, 4, 5];
let index = arr.indexOf(3); // index 是 2

lastIndexOf() - 返回数组中最后一个匹配元素的索引,如果没有找到则返回 -1

1
2
let arr = [1, 2, 3, 4, 3, 5];
let lastIndex = arr.lastIndexOf(3); // lastIndex 是 4

find() - 返回数组中第一个匹配条件的元素,如果没有找到则返回 undefined

1
2
let arr = [1, 2, 3, 4, 5];
let found = arr.find(element => element > 3); // found 是 4

findIndex() - 返回数组中第一个匹配条件的元素的索引,如果没有找到则返回 -1

1
2
let arr = [1, 2, 3, 4, 5];
let foundIndex = arr.findIndex(element => element > 3); // foundIndex 是 3

3. 遍历数组

forEach() - 对数组中的每个元素执行一次给定的函数

1
2
3
let arr = [1, 2, 3, 4, 5];
arr.forEach(element => console.log(element));
// 输出:1 2 3 4 5

map() - 创建一个新数组,其元素是调用一次提供的函数后的返回值

1
2
let arr = [1, 2, 3, 4, 5];
let squares = arr.map(element => element * element); // squares 是 [1, 4, 9, 16, 25]

filter() - 创建一个新数组,包含通过所提供函数实现的测试的所有元素

1
2
let arr = [1, 2, 3, 4, 5];
let evenNumbers = arr.filter(element => element % 2 === 0); // evenNumbers 是 [2, 4]

reduce() - 对数组中的所有元素执行一个由左到右的归并操作,将其归并为单个返回值

1
2
let arr = [1, 2, 3, 4, 5];
let sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0); // sum 是 15

reduceRight() - 对数组中的所有元素执行一个由右到左的归并操作,将其归并为单个返回值

1
2
let arr = [1, 2, 3, 4, 5];
let sum = arr.reduceRight((accumulator, currentValue) => accumulator + currentValue, 0); // sum 是 15

4. 排序和反转

sort() - 对数组的元素进行原地排序,并返回数组

1
2
let arr = [3, 1, 4, 1, 5, 9, 2, 6];
arr.sort(); // arr 现在是 [1, 1, 2, 3, 4, 5, 6, 9]

reverse() - 对数组的元素进行原地反转,并返回数组

1
2
let arr = [1, 2, 3, 4, 5];
arr.reverse(); // arr 现在是 [5, 4, 3, 2, 1]

5. 拷贝和合并

slice() - 创建一个新数组,包含从开始到结束(不包括结束)的数组中的元素

1
2
let arr = [1, 2, 3, 4, 5];
let subArray = arr.slice(1, 3); // subArray 是 [2, 3]

concat() - 创建一个新数组,包含原数组和一个或多个其他数组或值的组合

1
2
3
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let newArr = arr1.concat(arr2); // newArr 是 [1, 2, 3, 4, 5, 6]

6. 其他方法

join() - 将数组的所有元素连接成一个字符串,并返回这个字符串

1
2
let arr = [1, 2, 3, 4, 5];
let str = arr.join(', '); // str 是 "1, 2, 3, 4, 5"

includes() - 检查数组是否包含某个值,如果是则返回 true,否则返回 false

1
2
let arr = [1, 2, 3, 4, 5];
let contains = arr.includes(3); // contains 是 true

every() - 测试数组中的所有元素是否都通过了提供的函数测试,如果是则返回 true,否则返回 false

1
2
let arr = [1, 2, 3, 4, 5];
let allPositive = arr.every(element => element > 0); // allPositive 是 true

some() - 测试数组中的至少一个元素是否通过了提供的函数测试,如果是则返回 true,否则返回 false

1
2
let arr = [1, 2, 3, 4, 5];
let hasPositive = arr.some(element => element > 0); // hasPositive 是 true

fill() - 用一个固定值填充数组的从起始索引到终止索引内的元素

1
2
let arr = [1, 2, 3, 4, 5];
arr.fill(0, 2, 4); // arr 现在是 [1, 2, 0, 0, 5]

copyWithin() - 浅复制数组的一部分到同一数组中的另一个位置,并返回它,不修改其大小

1
2
let arr = [1, 2, 3, 4, 5];
arr.copyWithin(0, 3); // arr 现在是 [4, 5, 3, 4, 5]

总结

JavaScript 数组提供了丰富的方法来操作和处理数组,这些方法可以满足大多数常见的需求。通过合理使用这些方法,可以更高效地编写和管理数组相关的代码。

伪数组

伪数组(类数组对象)是指具有某些数组特征但又不是真正的数组对象的数据结构。以下是关于伪数组的详细介绍:

一、伪数组的特点

  1. 具有length属性
    • 伪数组通常具有一个length属性,表示其包含的元素数量。例如,arguments对象是一个常见的伪数组,它在函数中用于访问函数的参数。每个arguments对象都有一个length属性,表示传入函数的参数个数。
      1
      2
      3
      4
      5
      6
      7
      function myFunction() {
      console.log(arguments.length); // 输出传入的参数个数
      for (let i = 0; i < arguments.length; i++) {
      console.log(arguments[i]); // 访问每个参数
      }
      }
      myFunction(1, 'a', true); // 输出 3,然后依次输出 1、'a'、true
  2. 元素可通过索引访问
    • 伪数组的元素可以通过索引(从0开始)进行访问,就像数组一样。例如,arguments[0]可以访问第一个参数,arguments[1]可以访问第二个参数等。
  3. 不是真正的数组实例
    • 伪数组不是真正的数组对象,它不能直接使用数组的原型方法,如pushpopmapforEach等。例如,arguments.push()会报错,因为arguments对象没有push方法。
      1
      2
      3
      function myFunction() {
      // arguments.push(4); // TypeError: arguments.push is not a function
      }

二、常见的伪数组

  1. arguments对象
    • arguments对象是函数的内置对象,用于访问函数的参数。它是一个伪数组,具有length属性,可以通过索引访问参数。
  2. DOM集合
    • 许多DOM操作返回的结果也是伪数组。例如,document.getElementsByTagNamedocument.getElementsByClassNamedocument.querySelectorAll等方法返回的都是伪数组对象。
      1
      2
      3
      4
      5
      let divs = document.getElementsByTagName('div');
      console.log(divs.length); // 输出页面中div元素的数量
      for (let i = 0; i < divs.length; i++) {
      console.log(divs[i]); // 访问每个div元素
      }
      这些DOM集合对象也具有length属性,并且可以通过索引访问每个元素,但它们不是真正的数组实例。

三、如何将伪数组转换为真正的数组

  1. 使用Array.prototype.slice方法
    • 可以使用Array.prototype.slice方法将伪数组转换为真正的数组。slice方法可以接受一个伪数组作为this上下文,并返回一个真正的数组。
      1
      2
      3
      4
      5
      6
      7
      function myFunction() {
      let args = Array.prototype.slice.call(arguments);
      console.log(args); // 输出一个真正的数组
      args.push(4); // 可以使用数组方法
      console.log(args); // 输出 [1, 'a', true, 4]
      }
      myFunction(1, 'a', true);
  2. 使用扩展运算符(ES6)
    • 在ES6中,可以使用扩展运算符(...)更简洁地将伪数组转换为真正的数组。
      1
      2
      3
      4
      5
      6
      7
      function myFunction() {
      let args = [...arguments];
      console.log(args); // 输出一个真正的数组
      args.pop(); // 可以使用数组方法
      console.log(args); // 输出 [1, 'a']
      }
      myFunction(1, 'a', true);
  3. 使用Array.from方法(ES6)
    • Array.from方法可以将伪数组转换为真正的数组。它接受一个类数组对象或可迭代对象,并返回一个真正的数组。
      1
      2
      3
      4
      5
      6
      function myFunction() {
      let args = Array.from(arguments);
      console.log(args); // 输出一个真正的数组
      args.forEach(item => console.log(item)); // 可以使用数组方法
      }
      myFunction(1, 'a', true);

通过以上方法,可以将伪数组转换为真正的数组,从而能够使用数组的原型方法进行操作。

Js数组和对象相互转化

在JavaScript中,数组和对象之间的相互转换是常见的操作。以下是一些基本的方法来实现这种转换:

数组转对象

  1. 使用reduce方法
    将数组转换为对象,其中数组的每个元素应该是一个包含键和值的子数组。
    1
    2
    3
    4
    5
    6
    7
    8
    let array = ['key1', 'value1', 'key2', 'value2'];
    let obj = array.reduce((acc, curr, index, arr) => {
    if (index % 2 === 0) {
    acc[arr[index]] = arr[index + 1];
    }
    return acc;
    }, {});
    console.log(obj); // { key1: 'value1', key2: 'value2' }
  2. 使用Object.assignObject.fromEntries方法(需要迭代器):
    如果你的数组是键值对的形式,可以使用Object.fromEntries方法。
    1
    2
    3
    let array = [['key1', 'value1'], ['key2', 'value2']];
    let obj = Object.fromEntries(array);
    console.log(obj); // { key1: 'value1', key2: 'value2' }

对象转数组

  1. 使用Object.keysObject.valuesObject.entries方法
    将对象的键、值或键值对转换为数组。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let obj = { key1: 'value1', key2: 'value2' };
    // 转换为键数组
    let keys = Object.keys(obj);
    console.log(keys); // ['key1', 'key2']
    // 转换为值数组
    let values = Object.values(obj);
    console.log(values); // ['value1', 'value2']
    // 转换为键值对数组
    let entries = Object.entries(obj);
    console.log(entries); // [['key1', 'value1'], ['key2', 'value2']]
  2. 使用for...in循环
    通过遍历对象的属性来创建数组。
    1
    2
    3
    4
    5
    6
    7
    8
    let obj = { key1: 'value1', key2: 'value2' };
    let array = [];
    for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
    array.push([key, obj[key]]);
    }
    }
    console.log(array); // [['key1', 'value1'], ['key2', 'value2']]
  3. 使用Object.assign方法
    将对象转换为数组,首先将对象转换为JSON字符串,然后再将字符串转换为数组。
    1
    2
    3
    let obj = { key1: 'value1', key2: 'value2' };
    let array = JSON.parse(JSON.stringify(obj));
    console.log(array); // {"key1":"value1","key2":"value2"},注意这是一个对象,不是数组
    请注意,最后一个方法实际上并没有将对象转换为数组,而是转换成了一个JSON字符串,然后再将这个字符串解析为一个对象。如果你需要一个真正的数组,你可能需要使用其他方法,比如Object.valuesObject.entries