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 undefinedjedem 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():
callbackwird 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.