Anda dapat melakukannya:
var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)
hasil: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
atau dengan nilai acak:
Array.apply(null, {length: N}).map(Function.call, Math.random)
hasil: [0.7082694901619107, 0.9572225909214467, 0.8586748542729765, 0.8653848143294454, 0.008339877473190427, 0.9911756622605026, 0.8133423360995948, 0.837758846580948303530
Penjelasan
Pertama, perhatikan yang Number.call(undefined, N)
setara dengan Number(N)
, yang baru saja kembali N
. Kami akan menggunakan fakta itu nanti.
Array.apply(null, [undefined, undefined, undefined])
setara dengan Array(undefined, undefined, undefined)
, yang menghasilkan array tiga elemen dan menetapkan undefined
untuk setiap elemen.
Bagaimana Anda bisa menggeneralisasikannya ke elemen N ? Pertimbangkan cara Array()
kerjanya, yang kira-kira seperti ini:
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;
}
Sejak ECMAScript 5 , Function.prototype.apply(thisArg, argsArray)
juga menerima objek seperti array bebek-mengetik sebagai parameter kedua. Jika kita memohon Array.apply(null, { length: N })
, maka itu akan dieksekusi
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.push(/* arguments[i] = */ undefined);
}
return a;
}
Sekarang kita memiliki array N- elemen, dengan setiap elemen diatur ke undefined
. Ketika kita memanggilnya .map(callback, thisArg)
, setiap elemen akan diatur ke hasil callback.call(thisArg, element, index, array)
. Oleh karena itu, [undefined, undefined, …, undefined].map(Number.call, Number)
akan memetakan setiap elemen (Number.call).call(Number, undefined, index, array)
, yang sama dengan Number.call(undefined, index, array)
, yang, seperti yang kami amati sebelumnya, dievaluasi index
. Itu melengkapi array yang elemennya sama dengan indeks mereka.
Mengapa harus melalui masalah Array.apply(null, {length: N})
bukan hanya Array(N)
? Setelah semua, kedua ekspresi akan menghasilkan array N -elemen elemen yang tidak terdefinisi. Perbedaannya adalah bahwa dalam ekspresi sebelumnya, setiap elemen secara eksplisit diatur ke tidak terdefinisi, sedangkan pada yang terakhir, setiap elemen tidak pernah ditetapkan. Menurut dokumentasi .map()
:
callback
dipanggil hanya untuk indeks array yang telah menetapkan nilai; itu tidak dipanggil untuk indeks yang telah dihapus atau yang tidak pernah diberi nilai.
Karena itu, Array(N)
tidak cukup; Array(N).map(Number.call, Number)
akan menghasilkan sebuah array diinisiasi panjang N .
Kesesuaian
Karena teknik ini bergantung pada perilaku yang Function.prototype.apply()
ditentukan dalam ECMAScript 5, itu tidak akan berfungsi di browser pra-ECMAScript 5 seperti Chrome 14 dan Internet Explorer 9.