Sebagian besar tutorial yang saya baca pada array dalam JavaScript (termasuk w3schools dan devguru ) menyarankan Anda untuk menginisialisasi array dengan panjang tertentu dengan mengirimkan integer ke konstruktor Array menggunakan var test = new Array(4);
sintaks.
Setelah menggunakan sintaks ini secara bebas di file js saya, saya menjalankan salah satu file melalui jsLint , dan itu panik:
Kesalahan: Masalah pada karakter baris 1 22: Diharapkan ')' dan sebaliknya melihat '4'.
var test = new Array (4);
Masalah pada baris 1 karakter 23: Diharapkan ';' dan bukannya melihat ')'.
var test = new Array (4);
Masalah pada baris 1 karakter 23: Diharapkan pengidentifikasi dan bukannya melihat ')'.
Setelah membaca penjelasan jsLint tentang perilakunya , sepertinya jsLint tidak benar-benar menyukai new Array()
sintaks, dan sebaliknya lebih suka []
ketika mendeklarasikan array.
Jadi saya punya beberapa pertanyaan:
Pertama, mengapa? Apakah saya menjalankan risiko dengan menggunakan new Array()
sintaks? Apakah ada ketidakcocokan browser yang harus saya ketahui?
Dan kedua, jika saya beralih ke sintaks braket persegi, apakah ada cara untuk mendeklarasikan array dan mengatur panjangnya semua pada satu baris, atau apakah saya harus melakukan sesuatu seperti ini:
var test = [];
test.length = 4;
sumber
new Array()
secara umum, tapi tidak apa-apa dengan menentukan ukuran. Saya pikir semuanya bermuara pada konsistensi kode melalui keseluruhan konteks.Jawaban:
Mengapa Anda ingin menginisialisasi panjangnya? Secara teoritis tidak perlu untuk ini. Itu bahkan dapat mengakibatkan perilaku membingungkan, karena semua tes yang menggunakan
length
untuk mengetahui apakah array kosong atau tidak akan melaporkan bahwa array tidak kosong.Beberapa tes menunjukkan bahwa pengaturan panjang awal array besar bisa lebih efisien jika array diisi setelahnya, tetapi kinerja yang didapat (jika ada) tampaknya berbeda dari browser ke browser.
jsLint tidak suka
new Array()
karena konstruktornya ambigu.menciptakan array kosong dengan panjang 4. Tapi
menciptakan array yang berisi nilai
'4'
.Mengenai komentar Anda: Di JS Anda tidak perlu menginisialisasi panjang array. Itu tumbuh secara dinamis. Anda bisa menyimpan panjang dalam beberapa variabel, misalnya
sumber
for
loop yang berulang di atas panjang array dan mengisinya. Saya kira akan ada cara lain untuk melakukan ini dalam JavaScript, jadi jawaban sebenarnya untuk "Mengapa saya ingin melakukan ini?" adalah "Karena kebiasaan lama yang terbentuk saat pemrograman dalam bahasa lain." :)new Array(10)
tidak membuat array dengan 10 elemen yang tidak ditentukan. Ini hanya menciptakan array kosong dengan panjang 10. Lihat jawaban ini untuk kebenaran yang buruk: stackoverflow.com/questions/18947892/…Array(5)
memberi Anda sebuah array dengan panjang 5 tetapi tidak ada nilai, maka Anda tidak bisa mengulanginya.Array.apply(null, Array(5)).map(function () {})
memberi Anda sebuah array dengan panjang 5 dan tidak terdefinisi sebagai nilai, sekarang bisa diulangi.Array.apply(null, Array(5)).map(function (x, i) { return i; })
memberi Anda sebuah array dengan panjang 5 dan nilai 0,1,2,3,4.Array(5).forEach(alert)
tidak melakukan apa-apa,Array.apply(null, Array(5)).forEach(alert)
memberi Anda 5 peringatanES6
memberi kamiArray.from
jadi sekarang Anda juga dapat menggunakanArray.from(Array(5)).forEach(alert)
Jika Anda ingin menginisialisasi dengan nilai tertentu, ini bagus untuk diketahui ...
Array.from('abcde')
,Array.from('x'.repeat(5))
atau
Array.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
sumber
Array
diberikan beberapa argumen, ia mengulangiarguments
objek dan secara eksplisit menerapkan setiap nilai ke array baru. Ketika Anda memanggilArray.apply
dengan array atau objek dengan properti panjangArray
akan menggunakan panjang untuk secara eksplisit mengatur setiap nilai array baru. Inilah sebabnya mengapaArray(5)
memberikan array 5 elisions, sementaraArray.apply(null, Array(5))
memberikan array 5 undefined. Untuk informasi lebih lanjut, lihat jawaban ini .Array.apply(null, Array(5))
juga dapat ditulis sebagaiArray.apply(null, {length: 5})
. Sebenarnya tidak ada banyak perbedaan, tetapi yang terakhir jelas bahwa tujuannya adalah untuk membuat arraylength 5
, dan bukan array yang mengandung5
Dengan ES2015
.fill()
sekarang Anda bisa melakukan:Yang jauh lebih ringkas daripada
Array.apply(0, new Array(n)).map(i => value)
Hal ini dimungkinkan untuk menjatuhkan
0
di.fill()
dan berjalan tanpa argumen, yang akan mengisi array denganundefined
. ( Namun, ini akan gagal di dalam Skrip )sumber
When Array is called as a function rather than as a constructor, it also creates and initializes a new Array object. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments
Array(n).fill()
ATAU
Catatan: Anda tidak dapat mengulangi slot kosong yaitu
Array(4).forEach(() => …)
ATAU
( naskah aman )
ATAU
Metode klasik menggunakan fungsi (berfungsi di browser apa saja)
Membuat array bersarang
Saat membuat array 2D dengan
fill
intuitif harus membuat instance baru. Tetapi apa yang sebenarnya akan terjadi adalah array yang sama akan disimpan sebagai referensi.Larutan
Jadi Array 3x2 akan terlihat seperti ini:
Array N-dimensi
Inisialisasi papan catur
sumber
a[0].push(9);
// [ [6, 9], [6], [6] ]
seharusnyaa[0].push(9);
// [ [6, 9], [6, 9], [6, 9] ]
karena setiap array bersarang disimpan sebagai referensi, sehingga bermutasi satu array mempengaruhi sisanya. Anda mungkin salah ketik, meskipun saya pikir :)Terpendek:
sumber
[
tanpa menggunakan;
karena akan mencoba untuk meringkas garis di atas. Jadi cara yang aman untuk menggunakan baris ini dapat diprediksi di bagian mana pun dari kode adalah:;[...Array(1000)]//.whateverOpsNeeded()
[...Array(5)].map((item, index) => ({ index }))
coba ini juga:[...Array(5)]; console.log('hello');
const a = 'a'
dan baris berikutnya[...Array(5)].//irrelevent
. Menurut Anda apa yang akan diselesaikan oleh baris pertama? Ituconst a = 'a'[...Array(5)]
yang akan menghasilkan:Uncaught SyntaxError: Unexpected token ...
const a = 'a'
akan menjadi kesalahan Lint dalam kasus itu. Bagaimanapun, itu benar-benar tidak ada hubungannya dengan jawaban ini.Memperkenalkan ES6
Array.from
yang memungkinkan Anda membuatArray
dari setiap "array-seperti" atau iterables objek:Dalam hal ini
{length: 10}
mewakili definisi minimal objek "seperti array" : objek kosong dengan hanyalength
properti yang ditentukan.Array.from
memungkinkan argumen kedua untuk memetakan di atas array yang dihasilkan.sumber
Ini akan menginisialisasi properti panjang menjadi 4:
sumber
var size = 42; var myArray = eval("["+",".repeat(size)+"]");
? (Tidak seserius itu;)Saya terkejut belum ada solusi fungsional yang disarankan yang memungkinkan Anda untuk mengatur panjang dalam satu baris. Berikut ini didasarkan pada UnderscoreJS:
Untuk alasan yang disebutkan di atas, saya akan menghindari melakukan ini kecuali saya ingin menginisialisasi array ke nilai tertentu. Sangat menarik untuk dicatat ada perpustakaan lain yang mengimplementasikan jangkauan termasuk Lo-dash dan Lazy, yang mungkin memiliki karakteristik kinerja yang berbeda.
sumber
Tolonglah orang-orang tidak meninggalkan kebiasaan lama Anda dulu. Ada perbedaan besar dalam kecepatan antara mengalokasikan memori sekali kemudian bekerja dengan entri dalam array itu (seperti yang lama), dan mengalokasikannya berkali-kali ketika array tumbuh (yang tidak dapat dihindari apa yang dilakukan sistem di bawah tenda dengan metode yang disarankan lainnya) .
Tentu saja tidak ada yang penting, sampai Anda ingin melakukan sesuatu yang keren dengan array yang lebih besar. Lalu itu terjadi.
Melihat sepertinya masih ada opsi di JS saat ini untuk mengatur kapasitas awal array, saya menggunakan yang berikut ...
Ada pengorbanan yang terlibat:
standard
Array tidak permanen cadangan ruang sebanyak array terbesar Anda minta.Tetapi jika itu sesuai dengan apa yang Anda lakukan, mungkin ada hasilnya. Penempatan waktu yang tidak resmi
di cukup cepat (sekitar 50 ms untuk 10.000 mengingat bahwa dengan n = 1000000 butuh sekitar 5 detik), dan
lebih dari satu menit (sekitar 90 detik untuk 10.000 pada konsol chrome yang sama, atau sekitar 2000 kali lebih lambat). Itu tidak hanya alokasi, tetapi juga 10.000 dorongan, untuk loop, dll.
sumber
(ini mungkin lebih baik sebagai komentar, tetapi terlalu lama)
Jadi, setelah membaca ini saya ingin tahu apakah pra-alokasi sebenarnya lebih cepat, karena secara teori seharusnya. Namun, blog ini memberikan beberapa saran untuk mencegahnya http://www.html5rocks.com/en/tutorials/speed/v8/ .
Jadi masih ragu, saya mengujinya. Dan ternyata itu ternyata lebih lambat.
Kode ini menghasilkan yang berikut setelah beberapa santai berjalan:
sumber
sumber
[5: 0]
ini adalah array yang jarang dan mungkin bukan yang diinginkan.Ini solusi lain
Argumen pertama
apply()
adalah objek yang mengikat ini, yang tidak kami pedulikan di sini, jadi kami aturnull
.Array.apply(..)
memanggilArray(..)
fungsi dan menyebarkan nilai{ length: 3 }
objek sebagai argumennya.sumber
new Array(n)
untuk menginisialisasi array seperti ininew Array(n).map(function(notUsed,index){...})
, tetapi dengan pendekatan ini, seperti yang disebutkan @ zangw, Anda dapat melakukannya. +1 dari saya.Konstruktor array memiliki sintaks yang ambigu , dan JSLint hanya menyakiti perasaan Anda.
Juga, kode contoh Anda rusak,
var
pernyataan kedua akan memunculkan aSyntaxError
. Anda sedang mengatur propertilength
arraytest
, jadi tidak perlu yang lainvar
.Sejauh pilihan Anda,
array.length
adalah satu-satunya "bersih". Pertanyaannya adalah, mengapa Anda perlu mengatur ukuran di tempat pertama? Cobalah untuk memperbaiki kode Anda untuk menghilangkan ketergantungan itu.sumber
var test
. Itu adalah salinan dan tempelan ceroboh di pihak saya.Dengan asumsi bahwa panjang Array adalah konstan. Dalam Javascript, Ini yang kami lakukan:
const intialArray = new Array(specify the value);
sumber
Seperti dijelaskan di atas, menggunakan
new Array(size)
agak berbahaya. Alih-alih menggunakannya secara langsung, letakkan di dalam "fungsi pembuat array". Anda dapat dengan mudah memastikan bahwa fungsi ini bebas bug dan Anda terhindar dari bahaya meneleponnew Array(size)
langsung. Selain itu, Anda dapat memberikan nilai awal default opsional.createArray
Fungsi ini melakukan hal itu:sumber
Dalam sebagian besar jawaban, disarankan ke
fill
array karena jika tidak, "Anda tidak dapat mengulanginya" , tetapi ini tidak benar. Anda dapat mengulangi array yang kosong, hanya saja tidak denganforEach
. Sementara loop, untuk loop dan untuk loop saya bekerja dengan baik.Tidak bekerja.
Pekerjaan ini:
Periksa biola ini dengan contoh di atas.
Juga angulars
*ngFor
berfungsi dengan baik dengan array kosong:sumber
Anda dapat mengatur panjang array dengan menggunakan
array.length = youValue
Jadi itu akan terjadi
sumber
Alasan Anda tidak boleh menggunakan
new Array
ditunjukkan oleh kode ini:Beberapa kode lain dapat mengacaukan dengan variabel Array. Saya tahu ini agak terlalu jauh bahwa siapa pun akan menulis kode seperti itu, tetapi masih ...
Juga, seperti yang dikatakan Felix King, antarmuka sedikit tidak konsisten, dan dapat menyebabkan beberapa bug yang sangat sulit dilacak.
Jika Anda menginginkan array dengan length = x, diisi dengan undefined (seperti yang
new Array(x)
akan dilakukan), Anda bisa melakukan ini:sumber
alert
danundefined
, karena beberapa kode lain dapat mengacaukannya. Contoh kedua kurang dapat dibaca daripadanew Array(4)
, dan tidak memberi Anda hasil yang sama: jsfiddle.net/73fKd