1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
---
title: Array.from()
slug: Web/JavaScript/Reference/Global_Objects/Array/from
tags:
- Array
- ECMAScript 2015
- JavaScript
- Reference
- arguments
- polyfill
- 参考
- 数组
translation_of: Web/JavaScript/Reference/Global_Objects/Array/from
---
<div>{{JSRef}}</div>
<p><code><strong>Array.from()</strong></code> 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。</p>
<div>{{EmbedInteractiveExample("pages/js/array-from.html")}}</div>
<h2 id="语法">语法</h2>
<pre class="syntaxbox notranslate">Array.from(<em>arrayLike</em>[, <em>mapFn</em>[, <em>thisArg</em>]])
</pre>
<h3 id="参数">参数</h3>
<dl>
<dt><code>arrayLike</code></dt>
<dd>想要转换成数组的伪数组对象或可迭代对象。</dd>
<dt><code>mapFn</code> {{Optional_inline}}</dt>
<dd>如果指定了该参数,新数组中的每个元素会执行该回调函数。</dd>
<dt><code>thisArg</code> {{Optional_inline}}</dt>
<dd>可选参数,执行回调函数 <code>mapFn</code> 时 <code>this</code> 对象。</dd>
</dl>
<h3 id="返回值">返回值</h3>
<p>一个新的{{jsxref("Array","数组")}}实例。</p>
<h2 id="描述">描述</h2>
<p><code>Array.from()</code> 可以通过以下方式来创建数组对象:</p>
<ul>
<li>伪数组对象(拥有一个 <code>length</code> 属性和若干索引属性的任意对象)</li>
<li><a href="/zh-CN/docs/Web/JavaScript/Guide/iterable">可迭代对象</a>(可以获取对象中的元素,如 Map和 Set 等)</li>
</ul>
<p><code>Array.from()</code> 方法有一个可选参数 <code>mapFn</code>,让你可以在最后生成的数组上再执行一次 {{jsxref("Array.prototype.map", "map")}} 方法后再返回。也就是说<code> Array.from(obj, mapFn, thisArg) </code>就相当于<code> Array.from(obj).map(mapFn, thisArg),</code> 除非创建的不是可用的中间数组。 这对一些数组的子类<code>,</code>如 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays">typed arrays</a><font face="Consolas, Liberation Mono, Courier, monospace"> 来说很重要,</font> 因为中间数组的值在调用 map() 时需要是适当的类型。</p>
<p><code>from()</code> 的 <code>length</code> 属性为 1 ,即 <code>Array.from.length === 1</code>。</p>
<p>在 ES2015 中, <code>Class</code> 语法允许我们为内置类型(比如 <code>Array</code>)和自定义类新建子类(比如叫 <code>SubArray</code>)。这些子类也会继承父类的静态方法,比如 <code>SubArray.from()</code>,调用该方法后会返回子类 <code>SubArray</code> 的一个实例,而不是 <code>Array</code> 的实例。</p>
<h2 id="示例">示例</h2>
<h3 id="从_String_生成数组">从 <code>String</code> 生成数组</h3>
<pre class="brush: js notranslate">Array.from('foo');
// [ "f", "o", "o" ]</pre>
<h3 id="从_Set_生成数组">从 <code>Set</code> 生成数组</h3>
<pre class="brush: js notranslate">const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// [ "foo", "bar", "baz" ]</pre>
<h3 id="从_Map_生成数组">从 <code>Map</code> 生成数组</h3>
<pre class="brush: js notranslate">const map = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(map);
// [[1, 2], [2, 4], [4, 8]]
const mapper = new Map([['1', 'a'], ['2', 'b']]);
Array.from(mapper.values());
// ['a', 'b'];
Array.from(mapper.keys());
// ['1', '2'];
</pre>
<h3 id="从类数组对象(arguments)生成数组">从类数组对象(arguments)生成数组</h3>
<pre class="brush: js notranslate">function f() {
return Array.from(arguments);
}
f(1, 2, 3);
// [ 1, 2, 3 ]</pre>
<h3 id="在_Array.from_中使用箭头函数">在 <code>Array.from</code> 中使用箭头函数</h3>
<pre class="brush: js notranslate">// Using an arrow function as the map function to
// manipulate the elements
Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]
// Generate a sequence of numbers
// Since the array is initialized with `undefined` on each position,
// the value of `v` below will be `undefined`
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]
</pre>
<h3 id="序列生成器指定范围">序列生成器(指定范围)</h3>
<pre class="brush: js notranslate">// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
// Generate numbers range 0..4
range(0, 4, 1);
// [0, 1, 2, 3, 4]
// Generate numbers range 1..10 with step of 2
range(1, 10, 2);
// [1, 3, 5, 7, 9]
// Generate the alphabet using Array.from making use of it being ordered as a sequence
range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x));
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
</pre>
<h3 id="数组去重合并">数组去重合并</h3>
<pre class="brush: js notranslate">function combine(){
let arr = [].concat.apply([], arguments); //没有去重复的新数组
return Array.from(new Set(arr));
}
var m = [1, 2, 2], n = [2,3,3];
console.log(combine(m,n)); // [1, 2, 3]</pre>
<h2 id="Polyfill">Polyfill</h2>
<p>ECMA-262 第六版标准中添加了 <code>Array.from </code>。有些实现中可能尚未包括在其中。你可以通过在脚本前添加如下内容作为替代方法,以使用未原生支持的 <code>Array.from</code> 方法。该算法按照 ECMA-262 第六版中的规范实现,并假定 <code>Object</code> 和 <code>TypeError</code> 有其本身的值, <code>callback.call</code> 对应 {{jsxref("Function.prototype.call")}} 。此外,鉴于无法使用 Polyfill 实现真正的的迭代器,该实现不支持规范中定义的泛型可迭代元素。</p>
<pre class="brush: js notranslate">// Production steps of ECMA-262, Edition 6, 22.1.2.1
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
// The length property of the from method is 1.
return function from(arrayLike/*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;
// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);
// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requires an array-like object - not null or undefined");
}
// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
}
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
};
}());
}
</pre>
<h2 id="规范">规范</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ESDraft', '#sec-array.from', 'Array.from')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES2015', '#sec-array.from', 'Array.from')}}</td>
<td>{{Spec2('ES2015')}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p>{{Compat("javascript.builtins.Array.from")}}</p>
<h2 id="相关链接">相关链接</h2>
<ul>
<li>{{jsxref("Array")}}</li>
<li>{{jsxref("Array.prototype.map()")}}</li>
<li>{{jsxref("TypedArray.from()")}}</li>
</ul>
|