Saya berhati-hati untuk mengajukan pertanyaan ini karena mungkin terlihat terlalu rewel. Saya baru saja membuka JavaScript: Panduan Definitif, dan menyatakan halaman pertama bab 1
"JavaScript adalah bahasa pemrograman tingkat tinggi, dinamis, dan tidak ditafsirkan"
Jadi apakah saya harus menganggap bahwa bagian yang ditafsirkan adalah persyaratan dalam spesifikasi bahasa, atau apakah itu menyesatkan untuk mengatakan bahwa bahasa tersebut adalah bahasa pemrograman yang ditafsirkan ketika menghormati perbedaan antara bahasa dan banyak implementasinya?
Tampaknya tidak ada kompiler statis untuk JavaScript - https://stackoverflow.com/questions/1118138/is-there-a-nnative-machine-code-compiler-for-javascript jadi mungkin itu hanya cerminan dari ini.
sumber
Jawaban:
Geeks bahasa EcmaScript sering menggunakan istilah "ES interpreter" untuk merujuk pada implementasi EcmaScript, tetapi spec tidak menggunakan istilah itu. The gambaran bahasa khususnya menggambarkan bahasa dalam hal interpreter-agnostik:
Jadi EcmaScript mengasumsikan "lingkungan host" yang didefinisikan sebagai penyedia definisi objek termasuk semua yang memungkinkan I / O atau tautan lain ke dunia luar, tetapi tidak memerlukan juru bahasa.
Semantik pernyataan dan ungkapan dalam bahasa didefinisikan dalam hal spesifikasi penyelesaian yang sepele diimplementasikan dalam juru bahasa, tetapi spesifikasi tidak mengharuskan itu.
Transfer kontrol non-lokal dapat dikonversi ke array instruksi dengan lompatan yang memungkinkan untuk kompilasi kode asli atau byte.
"Mesin EcmaScript" mungkin cara yang lebih baik untuk mengekspresikan ide yang sama.
Ini tidak benar. V8 "interpreter" mengkompilasi ke kode asli secara internal, Rhino secara opsional mengkompilasi ke bytecode Java secara internal, dan berbagai penerjemah Mozilla ({Trace, Spider, Jager} Monkey) menggunakan kompiler JIT.
V8 :
Badak :
TraceMonkey :
sumber
de-optimization
langkah. Dengan kata lain JavaScript dikompilasi oleh mesin ini tetapi tidak dikompilasi secara statis.V8 JavaScript VM yang digunakan di Chrome tidak termasuk juru bahasa. Sebaliknya itu terdiri dari dua kompiler dan mengkompilasi kode dengan cepat. Salah satu kompiler berjalan cepat tetapi menghasilkan kode yang tidak efisien, yang lain adalah kompiler yang mengoptimalkan.
Saya bisa mengerti mengapa beberapa orang menganggap ini "curang", karena V8 mengambil kode sumber sebagai input setiap kali kode berjalan dan pengguna harus menginstal V8. Tetapi pertimbangkan kompiler yang memancarkan executable yang meliputi juru bahasa lengkap dan bytecode. Maka Anda akan memiliki program yang berdiri sendiri. Itu tidak akan sangat efisien.
sumber
Munculnya kompiler JIT untuk bahasa skrip telah mengaburkan batas antara kompilasi dan interpretasi ke titik di mana pertanyaannya tidak terlalu berarti. Apakah ini hanya interpretasi ketika mesin membaca sebaris kode dan segera menjalankannya? (Script shell masih biasanya diimplementasikan dengan cara ini.) Apakah ini interpretasi ketika mesin mengambil seluruh file, segera mengkompilasinya ke beberapa kode byte, dan kemudian mengartikan kode byte? (Mesin Mozilla tahap pertama bekerja dengan cara ini, seperti halnya CPython.) Apakah itu interpretasi ketika mesin mem-parsing suatu fungsi pada suatu waktu dan JIT-mengkompilasinya ke kode asli? Bagaimana dengan mesin-mesin yang mengkompilasi seluruh file ke kode byte, lalu JIT satu fungsi sekaligus sesuai kebutuhan? (Sebagian besar mesin skrip hari ini bekerja dengan cara ini,
Ada banyak corak antara kompilasi dan interpretasi.
Saya pikir definisi yang paling berguna untuk interpretasi adalah "diumpankan kode sumber program pada waktu eksekusi, tanpa langkah sebelumnya yang terpisah". Menurut definisi ini, semua mesin JavaScript adalah juru bahasa. Tetapi ini tentu saja bukan satu-satunya definisi interpretasi yang mungkin.
Tetapi apakah JavaScript dirancang untuk interpretasi? Di satu sisi, ya: ia memiliki
eval
fungsi sertaFunction
konstruktor yang dapat Anda berikan kode program sebagai string yang akan dieksekusi. Kemampuan untuk membuat kode program secara dinamis pada saat dijalankan mengharuskan engine mampu menginterpretasikan kode sumber. Tetapi ini tidak berarti bahwa Anda tidak dapat membuat segala sesuatu yang lain sebelumnya. Bahkan dalam bahasa yang dikompilasi seperti C ++ dan C # Anda dapat mengambil kode sumber, kompilasi dalam memori ke kode mesin baru dan kemudian jalankan itu. Bahkan ada perpustakaan untuk itu: LLVM + Dentang di C ++ dan proyek Roslyn di C #.Juga, mekanisme pengiriman untuk JavaScript adalah kode sumber; tidak ada bentuk kode byte yang dikenali darinya. C # dan Java memiliki kode byte resmi mereka, dan semua orang mengharapkan C ++ dikirimkan sebagai kode mesin. Namun ini masih bukan aspek bawaan jika bahasa, hanya skenario penggunaan dominan. Faktanya, ActionScript relatif dekat JavaScript di Flash sebenarnya dikirim sebagai kode byte (kompiler Flash mengkompilasi semua skrip).
sumber
Tidak ada yang sepenuhnya disepakati definisi 'ditafsirkan' versus 'dikompilasi'. Dalam perbedaan klasik, bahasa yang dikompilasi menghasilkan biner yang dapat dieksekusi, sementara bahasa yang ditafsirkan membutuhkan runtime yang digunakan untuk mengeksekusi kode. Mesin virtual, bytecode dan sebagainya mengaburkan perbedaan.
Tapi di sini ada definisi yang mungkin berguna: Bahasa yang ditafsirkan adalah bahasa di mana runtime bahasa standar dapat mengambil teks kode sumber sebagai input dan menjalankannya. Dengan definisi itu Perl, Python, Ruby, JavaScript dan skrip shell dan sejenisnya ditafsirkan (bahkan jika mereka menggunakan langkah-langkah menengah seperti bytecode atau bahkan kode asli). Java, C #, C dll tidak. Dan JavaScript menurut definisi ditafsirkan, bahkan jika spec tidak menggunakan kata yang tepat.
sumber