Sie können dies tun:
var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)
Ergebnis: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oder mit zufälligen Werten:
Array.apply(null, {length: N}).map(Function.call, Math.random)
Ergebnis: [0,7082694901619107, 0,9572225909214467, 0,8586748542729765, 0,8653848143294454, 0,008339877473190427, 0,9911756622605026, 0,8133423360995948, 0,8377588465809822, 0,8377575
Erläuterung
Beachten Sie zunächst, dass dies Number.call(undefined, N)
äquivalent zu ist Number(N)
, was gerade zurückgegeben wird N
. Wir werden diese Tatsache später nutzen.
Array.apply(null, [undefined, undefined, undefined])
ist äquivalent zu Array(undefined, undefined, undefined)
, das ein Array mit drei Elementen erzeugt und undefined
jedem Element zuweist .
Wie kann man das auf N Elemente verallgemeinern ? Überlegen Sie, wie es Array()
funktioniert, was ungefähr so aussieht:
function Array() {
if ( arguments.length == 1 &&
'number' === typeof arguments[0] &&
arguments[0] >= 0 && arguments &&
arguments[0] < 1 << 32 ) {
return [ … ]; // array of length arguments[0], generated by native code
}
var a = [];
for (var i = 0; i < arguments.length; i++) {
a.push(arguments[i]);
}
return a;
}
Da ECMAScript 5 , Function.prototype.apply(thisArg, argsArray)
akzeptiert auch eine Ente typisierte Array-ähnliches Objekt als zweiten Parameter. Wenn wir aufrufen Array.apply(null, { length: N })
, wird es ausgeführt
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.push(/* arguments[i] = */ undefined);
}
return a;
}
Jetzt haben wir ein N- Element-Array, auf das jedes Element gesetzt ist undefined
. Wenn wir es aufrufen .map(callback, thisArg)
, wird jedes Element auf das Ergebnis von gesetzt callback.call(thisArg, element, index, array)
. Daher [undefined, undefined, …, undefined].map(Number.call, Number)
würde jedes Element zugeordnet werden (Number.call).call(Number, undefined, index, array)
, was dasselbe ist Number.call(undefined, index, array)
, das, wie wir zuvor beobachtet haben, ausgewertet wird index
. Damit ist das Array vervollständigt, dessen Elemente mit ihrem Index übereinstimmen.
Warum sich die Mühe machen Array.apply(null, {length: N})
anstatt nur Array(N)
? Schließlich würden beide Ausdrücke ein N- Element-Array undefinierter Elemente ergeben. Der Unterschied ist , dass in dem früheren Ausdruck, wobei jedes Element explizit gesetzt zu undefinierten, wohingegen in den letzteren, wobei jedes Element nie gesetzt wurde. Nach der Dokumentation von .map()
:
callback
wird nur für Indizes des Arrays aufgerufen, denen Werte zugewiesen wurden; Es wird nicht für Indizes aufgerufen, die gelöscht wurden oder denen nie Werte zugewiesen wurden.
Daher Array(N)
ist nicht ausreichend; Array(N).map(Number.call, Number)
würde zu einem nicht initialisierten Array der Länge N führen .
Kompatibilität
Da diese Technik auf dem Function.prototype.apply()
in ECMAScript 5 angegebenen Verhalten beruht , funktioniert sie in Browsern vor ECMAScript 5 wie Chrome 14 und Internet Explorer 9 nicht.