Yah, pertama saya mungkin harus bertanya apakah ini tergantung pada browser.
Saya telah membaca bahwa jika token yang tidak valid ditemukan, tetapi bagian dari kode tersebut valid sampai token yang tidak valid itu, tanda titik koma dimasukkan sebelum token jika didahului oleh pemisah baris.
Namun, contoh umum yang dikutip untuk bug yang disebabkan oleh penyisipan titik koma adalah:
return
_a+b;
..yang tampaknya tidak mengikuti aturan ini, karena _a akan menjadi token yang valid.
Di sisi lain, memecah rantai panggilan berfungsi seperti yang diharapkan:
$('#myButton')
.click(function(){alert("Hello!")});
Adakah yang memiliki deskripsi aturan yang lebih mendalam?
Jawaban:
Pertama-tama Anda harus tahu pernyataan mana yang dipengaruhi oleh penyisipan titik koma otomatis (juga dikenal sebagai ASI untuk singkatnya):
var
pernyataando-while
pernyataancontinue
pernyataanbreak
pernyataanreturn
pernyataanthrow
pernyataanAturan konkret ASI, dijelaskan dalam spesifikasi §11.9.1 Aturan Penyisipan Titik Koma Otomatis
Tiga kasus dijelaskan:
Ketika token (
LineTerminator
atau}
) ditemui yang tidak diizinkan oleh tata bahasa, tanda titik koma dimasukkan sebelum itu jika:LineTerminator
.}
misalnya :
ditransformasikan menjadi
Yang
NumericLiteral
1
memenuhi kondisi pertama, token berikut adalah terminator garis.Yang
2
memenuhi kondisi kedua, token berikut adalah}
.Ketika akhir aliran input token ditemukan dan parser tidak dapat mengurai aliran token input sebagai Program tunggal yang lengkap, maka titik koma secara otomatis dimasukkan di akhir aliran input.
misalnya :
ditransformasikan menjadi:
Kasus ini terjadi ketika token diizinkan oleh beberapa produksi tata bahasa, tetapi produksi adalah produksi terbatas , tanda titik koma secara otomatis dimasukkan sebelum token terbatas.
Produksi terbatas:
Contoh klasik, dengan
ReturnStatement
:ditransformasikan menjadi
sumber
++c
untuk kejelasan?Langsung dari ECMA-262, Spesifikasi ECMAScript Fifth Edition :
sumber
Saya tidak dapat memahami 3 aturan dalam spesifikasi terlalu baik - berharap untuk memiliki sesuatu yang lebih sederhana dalam bahasa Inggris - tetapi di sini adalah apa yang saya kumpulkan dari JavaScript: Panduan Definitif, Edisi 6, David Flanagan, O'Reilly, 2011:
Mengutip:
Kutipan lain: untuk kode
dan:
Jadi saya pikir untuk menyederhanakannya, itu berarti:
Secara umum, JavaScript akan memperlakukannya sebagai kelanjutan dari kode selama itu masuk akal - kecuali 2 kasus: (1) setelah beberapa kata kunci seperti
return
,break
,continue
, dan (2) jika melihat++
atau--
pada baris baru, maka akan menambah yang;
pada akhir baris sebelumnya.Bagian tentang "memperlakukannya sebagai kelanjutan dari kode selama itu masuk akal" membuatnya terasa seperti pencocokan serakah ekspresi reguler.
Dengan kata di atas, itu artinya untuk
return
dengan istirahat baris, penerjemah JavaScript akan menyisipkan;
(dikutip lagi: Jika satu baris muncul setelah salah satu dari kata-kata ini [seperti
return
] ... JavaScript akan selalu menafsirkan garis tersebut sebagai titik koma)dan karena alasan ini, contoh klasik dari
tidak akan berfungsi seperti yang diharapkan, karena penerjemah JavaScript akan memperlakukannya sebagai:
Tidak boleh ada line-break segera setelah
return
:agar berfungsi dengan benar. Dan Anda dapat menyisipkan
;
diri Anda jika Anda mengikuti aturan menggunakan;
setelah pernyataan apa pun:sumber
Mengenai penyisipan titik koma dan pernyataan var, berhati-hatilah dengan melupakan koma saat menggunakan var tetapi menjangkau beberapa baris. Seseorang menemukan ini di kode saya kemarin:
Itu berjalan tetapi efeknya adalah bahwa deklarasi / penugasan srcIds bersifat global karena deklarasi lokal dengan var pada baris sebelumnya tidak lagi diterapkan karena pernyataan itu dianggap selesai karena penyisipan semi-kolon otomatis.
sumber
var srcRecords = src.records srcIds = [];
dalam satu baris dan lupakan koma atau Anda menulis "kembalikan a && b" dan jangan lupakan apa pun ... tetapi garis putus sebelum huruf a akan menyisipkan tanda titik koma otomatis setelah kembali, yang ditentukan oleh aturan ASI ...var
(let
,const
) pada setiap baris lebih besar daripada fraksi detik yang diperlukan untuk mengetiknya.Deskripsi paling kontekstual dari Penyisipan Titik Koma Otomatis JavaScript yang saya temukan berasal dari sebuah buku tentang Crafting Interpreters .
Dia melanjutkan untuk menggambarkannya seperti Anda akan kode bau .
sumber
Hanya untuk menambahkan,
lihat ini, menggunakan ekspresi fungsi yang langsung dipanggil (IIFE)
sumber