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
|
---
title: Array.from()
slug: Web/JavaScript/Referencia/Objetos_globales/Array/from
tags:
- ECMAScript 2015
- JavaScript
- Referencia
- Vector
- metodo
- polyfill
translation_of: Web/JavaScript/Reference/Global_Objects/Array/from
---
<div>{{JSRef}}</div>
<p>El método <code><strong>Array.from()</strong></code> crea una nueva instancia de <code>Array</code> a partir de un objeto iterable.</p>
<p>{{EmbedInteractiveExample("pages/js/array-from.html")}}</p>
<h2 id="Sintaxis">Sintaxis</h2>
<pre class="syntaxbox"><code>Array.from(arrayLike[, mapFn[, thisArg]])
</code></pre>
<h3 id="Parámetros">Parámetros</h3>
<dl>
<dt><code>arrayLike</code></dt>
<dd>Objeto iterable para convertirlo en un array.</dd>
<dt><code>mapFn</code>{{Optional_inline}}</dt>
<dd>Función de mapa para llamar a cada elemento de la matriz.</dd>
<dt><code>thisArg</code>{{Optional_inline}}</dt>
<dd>Valor para usar como <code>this</code> al ejecutar <code>mapFn</code>.</dd>
</dl>
<h3 id="Valor_de_retorno">Valor de retorno</h3>
<p>Una nueva instancia de {{jsxref("Array")}}.</p>
<h2 id="Descripción">Descripción</h2>
<p><code>Array.from()</code> permite crear <code>Arrays</code> de:</p>
<ul>
<li>Objetos array-like (objetos con propiedad <code>length</code> o elementos indexados).</li>
<li><a href="/es/docs/Web/JavaScript/Referencia/Iteration_protocols">Objetos iterables</a> (objetos de los cuales se pueden obtener sus elementos como {{jsxref("Map")}} y {{jsxref("Set")}}).</li>
</ul>
<p><code>Array.from()</code> tiene un parámetro opcional <code>mapFn</code>, que te permite ejecutar una función {{jsxref("Array.prototype.map", "map")}} a cada elemento del array (o a la subclase del objeto) que se ha creado. Para aclararlo, <code>Array.from(obj, mapFn, thisArg)</code> es igual que <code>Array.from(obj).map(mapFn, thisArg)</code>, excepto en que éste no crea un array intermedio. Esto es importante para ciertas subclases de array, <a href="/es/docs/Web/JavaScript/Vectores_tipados">vectores tipados</a>, ya que el vector intermedio necesitaría tener valores truncados para trabajar con el tipo adecuado.</p>
<p>La propiedad <code>length</code> del método <code>from()</code> es 1.</p>
<p>En ES2015, la sintaxis de clase permite la subclasificación de clases integradas y definidas por el usuario; como resultado, los métodos estáticos como <code>Array.from</code> son "heredados" por subclases de <code>Array</code> y crean nuevas instancias de la subclase, no <code>Array</code>.</p>
<h2 id="Ejemplos">Ejemplos</h2>
<h3 id="Array_desde_un_String">Array desde un <code>String</code></h3>
<pre class="brush: js">Array.from('foo');
// [ "f", "o", "o" ]</pre>
<h3 id="Array_desde_un_Set">Array desde un <code>Set</code></h3>
<pre class="brush: js">const set = new Set(['foo', 'bar', 'baz', 'foo']);
Array.from(set);
// [ "foo", "bar", "baz" ]</pre>
<h3 id="Array_desde_un_Map">Array desde un <code>Map</code></h3>
<pre class="brush: js">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="Array_desde_un_objeto_Array-like_(argumentos)">Array desde un objeto Array-like (argumentos)</h3>
<pre class="brush: js">function f() {
return Array.from(arguments);
}
f(1, 2, 3);
// [ 1, 2, 3 ]</pre>
<h3 id="Usando_una_función_de_flecha_y_Array.from">Usando una función de flecha y <code>Array.from</code></h3>
<pre class="brush: js">// Usando una función de flecha como función
// para manipular los elementos
Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]
// Generar secuencia de números
// Puesto que el array se inicializa con `undefined` en cada posición,
// el valor de `v` a continuación será `undefined`
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]
</pre>
<h3 id="Generador_de_secuencia_(rango)">Generador de secuencia (rango)</h3>
<pre class="brush: js">// Función generadora de secuencia (comúnmente llamado "rango", ej. Clojure, PHP, etc.)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
// Genera un rango de números entre 0..4
range(0, 4, 1);
// [0, 1, 2, 3, 4]
// Genera un rango de números entre 1..10 con saltos de 2
range(1, 10, 2);
// [1, 3, 5, 7, 9]
// Generar el abecedario utilizando Array.from haciendo uso de que se ordena como secuencia
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>
<h2 id="Polyfill">Polyfill</h2>
<p><code>Array.from</code> fue añadido en el estándar ECMA-262 en la 6ta edición (ES2015); así que no puede estar presente en otras implementaciones del estándar. Puedes usarlo insertando este código al comienzo de sus scripts, permitiendo el uso de <code>Array.from</code> en implementaciones que no lo soportan. Este algoritmo es el mismo especificado en ECMA-262, 6ta edición, suponiendo que <code>Object</code> y <code>TypeError</code> tengan sus valores originales y <code>callback.call</code> evalúa el valor original de {{jsxref("Function.prototype.call")}}. Adicionalmente, ya que verdaderos iterables pueden no ser polyficados, esta implementación no soporta iterables genéricos como definidos en la 6ta edición de ECMA-262.</p>
<pre class="brush: js">// Pasos de producción de ECMA-262, Edición 6, 22.1.2.1
// Referencia: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
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);
};
// La propiedad length del método from es 1.
return function from(arrayLike/*, mapFn, thisArg */) {
// 1. Deje a C ser el este valor.
var C = this;
// 2. Deje que los elementos sean ToObject(arrayLike).
var items = Object(arrayLike);
// 3. Retornar IfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requiere un objeto array-like - not null or undefined");
}
// 4. Si mapfn no está definida, entonces deja que sea false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. si no
// 5. a If IsCallable(mapfn) es false, lanza una excepción TypeError.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: si hay mapFn, el segundo argumento debe ser una función');
}
// 5. b. Si thisArg se suministró, deje que T sea thisArg; si no, deje que T esté indefinido.
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="Especificaciones">Especificaciones</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Especificación</th>
<th scope="col">Estado</th>
<th scope="col">Comentario</th>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-array.from', 'Array.from')}}</td>
<td>{{Spec2('ES6')}}</td>
<td>Definición inicial.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-array.from', 'Array.from')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidad_con_navegadores">Compatibilidad con navegadores</h2>
<div>
<p>{{Compat("javascript.builtins.Array.from")}}</p>
</div>
<h2 id="Ver_también">Ver también</h2>
<ul>
<li>{{jsxref("Array")}}</li>
<li>{{jsxref("Array.prototype.map()")}}</li>
<li>{{jsxref("TypedArray.from()")}}</li>
</ul>
|