> ## Content Index
> Fetch the complete content index at: https://iiong.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# JavaScript Array.from 详解
- URL: https://iiong.com/javascript-array-from-tutorial/
- Published: 2019-09-23T13:00:34.000Z
- Updated: 2026-06-22T15:31:05.000Z
- Description: Array.from允许在 JavaScript 集合(如: 数组、类数组对象、或者是字符串、map 、set 等可迭代对象) 上进行有用的转换。
- Author: 淮城一只猫
- Tags: 奇技淫巧

### Cap1 前言

`Array.from`：允许在 `JavaScript` 集合(如: 数组、类数组对象、或者是字符串、`map` 、`set` 等可迭代对象) 上进行有用的转换。

```javascript
Array.from(arrayLike[, mapFunction[, thisArg]])

```

- `arrayLike：`必传参数，想要转换成数组的伪数组对象或可迭代对象。
- `mapFunction：`可选参数，`mapFunction(item，index){...}` 是在集合中的每个项目上调用的函数。返回的值将插入到新集合中。
- `thisArg：`可选参数，执行回调函数 `mapFunction` 时 `this` 对象。这个参数很少使用。

### Cap2 将类数组转换成数组

`Array.from()` 第一个用途：将类数组对象转换成数组。平时会碰到的类数组对象有：函数中的 arguments 关键字，或者是一个 DOM 集合。

在下面的示例中，对函数的参数求和：

```javascript
function sumArguments() {
    return Array.from(arguments).reduce((sum, num) => sum + num);
}
 
sumArguments(1, 2, 3); // => 6

```

`Array.from(arguments)` 将类数组对象 `arguments` 转换成一个数组，然后使用数组的 `reduce` 方法求和。

此外，`Array.from()` 的第一个参数可以是任意一个可迭代对象：

```javascript
Array.from('Hey');                   // => ['H', 'e', 'y']
Array.from(new Set(['one', 'two'])); // => ['one', 'two']
 
const map = new Map();
map.set('one', 1)
map.set('two', 2);
Array.from(map); // => [['one', 1], ['two', 2]]

```

### Cap3 克隆数组

在 `JavaScript` 中有很多克隆数组的方法。`Array.from()` 可以很容易的实现数组的浅拷贝。

```javascript
const numbers = [3, 6, 9];
const numbersCopy = Array.from(numbers);
 
numbers === numbersCopy; // => false

```

`Array.from(numbers)` 创建了对 `numbers` 数组的浅拷贝，`numbers === numbersCopy` 的结果是 `false`，意味着虽然 `numbers` 和 `numbersCopy` 有着相同的项，但是它们是不同的数组对象。

是否可以使用 `Array.from()` 创建数组的克隆，包括所有嵌套的？挑战一下！

```javascript
function recursiveClone(val) {
    return Array.isArray(val) ? Array.from(val, recursiveClone) : val;
}
 
const numbers = [[0, 1, 2], ['one', 'two', 'three']];
const numbersClone = recursiveClone(numbers);
 
numbersClone; // => [[0, 1, 2], ['one', 'two', 'three']]
numbers[0] === numbersClone[0] // => false

```

`recursiveClone()` 能够对数组的深拷贝，通过判断 数组的 `item` 是否是一个数组，如果是数组，就继续调用 `recursiveClone()` 来实现了对数组的深拷贝。

你能编写一个比使用 `Array.from()` 递归拷贝更简短的数组深拷贝吗？如果可以的话，请写在下面的评论区。

### Cap4 使用值填充数组

如果需要使用相同的值来初始化数组，那么 `Array.from()` 将是不错的选择。定义一个函数，创建一个填充相同默认值的数组：

```javascript
const length = 3;
const init   = 0;
const result = Array.from({ length }, () => init);
 
result; // => [0, 0, 0]

```

`result` 是一个新的数组，它的长度为3，数组的每一项都是0。调用 `Array.from()` 方法，传入一个类数组对象 `{ length }` 和 返回初始化值的 `mapFunction` 函数。

但是，有一个替代方法 `array.fill()` 可以实现同样的功能。

```javascript
const length = 3;
const init   = 0;
const result = Array(length).fill(init);
 
fillArray2(0, 3); // => [0, 0, 0]

```

`fill()` 使用初始值正确填充数组。

### Cap5 使用对象填充数组

当初始化数组的每个项都应该是一个新对象时，`Array.from()` 是一个更好的解决方案：

```javascript
const length = 3;
const resultA = Array.from({ length }, () => ({}));
const resultB = Array(length).fill({});
 
resultA; // => [{}, {}, {}]
resultB; // => [{}, {}, {}]
 
resultA[0] === resultA[1]; // => false
resultB[0] === resultB[1]; // => true

```

由 `Array.from` 返回的 `resultA` 使用不同空对象实例进行初始化。之所以发生这种情况是因为每次调用时，`mapFunction`，即此处的 `() => ({})` 都会返回一个新的对象。

然后，`fill()` 方法创建的 `resultB` 使用相同的空对象实例进行初始化。不会跳过空项。

### Cap6 生成数字范围

可以使用 `Array.from()` 生成值范围。例如，下面的 `range` 函数生成一个数组，从0开始到 `end - 1`。

```javascript
function range(end) {
    return Array.from({ length: end }, (_, index) => index);
}
 
range(4); // => [0, 1, 2, 3]

```

在 `range()` 函数中，`Array.from()` 提供了类似数组的 `{length：end}` ，以及一个简单地返回当前索引的 `map` 函数 。这样就可以生成值范围。

### Cap7 数组去重

由于 `Array.from()` 的入参是可迭代对象，因此可以利用其与 `Set` 结合来实现快速从数组中删除重复项。

```javascript
function unique(array) {
  return Array.from(new Set(array));
}
 
unique([1, 1, 2, 3, 3]); // => [1, 2, 3]

```

首先，`new Set(array)` 创建了一个包含数组的集合，`Set` 集合会删除重复项。

因为 `Set` 集合是可迭代的，所以可以使用 `Array.from()` 将其转换为一个新的数组。

这样就实现了数组去重。

[MDN Web Docs](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global%5FObjects/Array/from?ref=iiong.com)