Lebih lanjut memperluas jawaban sebelumnya ...
Dari perspektif kompiler umum dan mengabaikan optimasi spesifik VM:
Pertama, kita melalui fase analisis leksikal di mana kita tokenize kode.
Sebagai contoh, token berikut dapat diproduksi:
[]: ARRAY_INIT
[1]: ARRAY_INIT (NUMBER)
[1, foo]: ARRAY_INIT (NUMBER, IDENTIFIER)
new Array: NEW, IDENTIFIER
new Array(): NEW, IDENTIFIER, CALL
new Array(5): NEW, IDENTIFIER, CALL (NUMBER)
new Array(5,4): NEW, IDENTIFIER, CALL (NUMBER, NUMBER)
new Array(5, foo): NEW, IDENTIFIER, CALL (NUMBER, IDENTIFIER)
Mudah-mudahan ini akan memberi Anda visualisasi yang cukup sehingga Anda dapat memahami berapa banyak (atau kurang) pemrosesan yang diperlukan.
Berdasarkan token di atas, kita tahu sebagai fakta ARRAY_INIT akan selalu menghasilkan array. Karena itu kami cukup membuat sebuah array dan mengisinya. Sejauh ambiguitas, tahap analisis leksikal telah membedakan ARRAY_INIT dari accessor properti objek (misalnya obj[foo]) atau tanda kurung di dalam string / regex literal (mis. "Foo [] bar" atau / [] /)
Ini sangat kecil, tetapi kami juga memiliki lebih banyak token new Array. Selain itu, belum sepenuhnya jelas bahwa kami hanya ingin membuat array. Kita melihat token "baru", tetapi "baru" apa? Kami kemudian melihat token IDENTIFIER yang menandakan kami menginginkan "Array" baru, tetapi JavaScript VM pada umumnya tidak membedakan token dan token IDENTIFIER untuk "objek global asli." Karena itu...
Kami harus mencari rantai cakupan setiap kali kami menemukan token IDENTIFIER. Javascript VMs berisi "objek Aktivasi" untuk setiap konteks eksekusi yang mungkin berisi objek "argumen", variabel yang ditentukan secara lokal, dll. Jika kita tidak dapat menemukannya di objek Aktivasi, kita mulai mencari rantai lingkup sampai kita mencapai lingkup global . Jika tidak ada yang ditemukan, kami melempar ReferenceError.
Setelah kami menemukan deklarasi variabel, kami memanggil konstruktor. new Arrayadalah pemanggilan fungsi implisit, dan aturan praktisnya adalah pemanggilan fungsi lebih lambat selama eksekusi (karenanya mengapa kompiler C / C ++ statis memungkinkan "fungsi inlining" - yang harus dilakukan mesin JS JIT seperti SpiderMonkey saat on-the-fly)
The Arraykonstruktor kelebihan beban. Konstruktor Array diimplementasikan sebagai kode asli sehingga memberikan beberapa peningkatan kinerja, tetapi masih perlu memeriksa panjang argumen dan bertindak sesuai. Selain itu, jika hanya ada satu argumen yang disediakan, kita perlu memeriksa lebih lanjut jenis argumen. Array baru ("foo") menghasilkan ["foo"] sedangkan Array baru (1) menghasilkan [tidak terdefinisi]
Jadi untuk menyederhanakan semuanya: dengan literal array, VM tahu kita menginginkan sebuah array; dengan new Array, VM perlu menggunakan siklus CPU tambahan untuk mencari tahu apa yang new Array sebenarnya dilakukan.