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 undefined
do 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()
:
callback
jest 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.