Możesz to zrobić:
var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)
wynik: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lub z losowymi wartościami:
Array.apply(null, {length: N}).map(Function.call, Math.random)
wynik: [0,7082694901619107, 0,9572225909214467, 0,8586748542729765, 0,8653848143294454, 0,008339877473190427, 0,9911756622605026, 0,8133423360995948, 0,8377588465809822, 0,557758303636454, 0,0753 930 955 364, 0,0753 930 955 0,475
Wyjaśnienie
Po pierwsze, zwróć uwagę na Number.call(undefined, N)to Number(N), co po prostu zwraca N. Wykorzystamy ten fakt później.
Array.apply(null, [undefined, undefined, undefined])jest równoważne z Array(undefined, undefined, undefined), który tworzy tablicę trzyelementową i przypisuje undefineddo każdego elementu.
Jak możesz to uogólnić na N elementów? Zastanów się, jak to Array()działa, co wygląda mniej więcej tak:
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;
}
Od ECMAScript 5 , Function.prototype.apply(thisArg, argsArray)przyjmuje również kaczki wpisany tablicowej obiekt jako drugi parametr. Jeśli wywołamy Array.apply(null, { length: N }), to się uruchomi
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.push(/* arguments[i] = */ undefined);
}
return a;
}
Teraz mamy tablicę N- element, z każdym elementem ustawionym na undefined. Kiedy .map(callback, thisArg)go wywołamy, każdy element zostanie ustawiony na wynik callback.call(thisArg, element, index, array). Dlatego [undefined, undefined, …, undefined].map(Number.call, Number)odwzorowałby każdy element na (Number.call).call(Number, undefined, index, array), który jest taki sam, jak Number.call(undefined, index, array), jak zaobserwowaliśmy wcześniej, ocenia index. To uzupełnia tablicę, której elementy są takie same jak ich indeks.
Po co męczyć się Array.apply(null, {length: N})zamiast po prostu Array(N)? Po tym wszystkim, oba wyrażenia spowoduje AN N -elementowe tablicę niezdefiniowanych elementów. Różnica polega na tym, że w pierwszym wyrażeniu każdy element jest jawnie ustawiony na niezdefiniowany, podczas gdy w drugim wyrażeniu każdy element nigdy nie był ustawiony. Zgodnie z dokumentacją .map():
callbackjest wywoływany tylko dla indeksów tablicy, którym przypisano wartości; nie jest wywoływany dla indeksów, które zostały usunięte lub którym nigdy nie przypisano wartości.
Dlatego Array(N)jest niewystarczający; Array(N).map(Number.call, Number)spowodowałoby niezainicjowanego matrycy o długości N .
Zgodność
Ponieważ ta technika opiera się na zachowaniu Function.prototype.apply()określonym w ECMAScript 5, nie będzie działać w przeglądarkach starszych niż ECMAScript 5, takich jak Chrome 14 i Internet Explorer 9.