Mengapa ini bekerja di Node.js
konsol (diuji pada 4.1.1 dan 5.3.0) tetapi tidak berfungsi di browser (diuji di Chrome)? Blok kode ini harus membuat dan menjalankan fungsi anonim yang mencatat Ok
.
() => {
console.log('Ok');
}()
Selain itu, sementara di atas berfungsi di Node, ini tidak berfungsi:
n => {
console.log('Ok');
}()
Atau ini:
(n) => {
console.log('Ok');
}()
Apa yang aneh adalah bahwa ketika parameter ditambahkan itu benar-benar melempar SyntaxError
pada bagian yang segera dipanggil.
(n => { console.log("Ok"); })();
berhasil?(n => { console.log("Ok"); })()
berfungsi bahkan di konsol dev ChromeNode.js
pertama sudah tidak berfungsi lagi.Jawaban:
Anda harus menjadikannya ekspresi fungsi alih-alih definisi fungsi yang tidak memerlukan nama dan menjadikannya JavaScript yang valid.
Apakah setara dengan IIFE
Dan alasan yang memungkinkan mengapa ini bekerja di Node.js tetapi tidak di chrome adalah karena parsernya mengartikannya sebagai fungsi yang mengeksekusi sendiri, karena ini
berfungsi dengan baik di
Node.js
Ini adalah ekspresi fungsi dan chrome dan firefox dan sebagian besar browser mengartikannya dengan cara ini. Anda harus menjalankannya secara manual.Cara yang paling banyak diterima untuk memberitahu parser untuk mengharapkan ekspresi fungsi adalah dengan membungkusnya dalam parens, karena dalam JavaScript, parens tidak dapat berisi pernyataan. Pada titik ini, ketika parser menemukan kata kunci fungsi, ia tahu menguraikannya sebagai ekspresi fungsi dan bukan deklarasi fungsi.
Mengenai versi parametrized , ini akan berhasil.
sumber
Node.js
dan benar-benar mencatat nilainya. Pertanyaan saya adalah mengapa cara kerjanya? Dan mengapa tidak ketika saya menambahkan parameter?IIFE
s dan tahu cara memperbaiki kode saya. Saya hanya ingin tahu mengapa, misalnya, sayaIIFE
tidak berfungsi ketikan
parameter ditambahkan, meskipun berfungsi tanpa parameter.function(){}()
dengan fungsi panah? Jika saya ingin fungsi objek terkena, ekspresi fungsi melindungi terhadap itu.Tak satu pun dari ini akan bekerja tanpa tanda kurung.
Mengapa?
Karena sesuai dengan spesifikasi:
Jadi ArrowFunction tidak bisa berada di LHS dari CallExpression .
Apa artinya ini secara efektif dalam bagaimana
=>
harus ditafsirkan, adalah bahwa ia bekerja pada tingkat yang sama dengan operator penugasan=
,+=
dll.Berartix => {foo}()
tidak menjadi(x => {foo})()
x => ({foo}())
Jadi penerjemah memutuskan bahwa(
pasti salah dan melemparkan SyntaxErrorAda bug pada Babel tentang hal itu di sini juga.
sumber
() => ({console.log('Ok')}())
tidak lagi berfungsi. Jadi itu tidak benar-benar menafsirkannya seperti itu.console.log(...)
bukan nama kunci yang valid.SyntaxError: Unexpected token (
(menunjuk ke(
dalam()
di akhir, bukan(
diconsole.log(...)
).(
Menyebabkan penerjemah menyerah setelah upaya yang melelahkan untuk menemukan interpretasi yang valid dan melanjutkan "Ini pasti salah kalau begitu"), yang mungkin juga salah karena saya tidak tahu bagaimana penerjemah itu benar-benar ditulisAlasan Anda melihat masalah seperti ini adalah konsol itu sendiri mencoba meniru lingkup global konteks yang saat ini Anda targetkan. Itu juga mencoba untuk menangkap nilai kembali dari pernyataan dan ekspresi yang Anda tulis di konsol, sehingga muncul sebagai hasil. Ambil, misalnya:
Di sini, dieksekusi seolah-olah itu ekspresi, tetapi Anda telah menulis seolah-olah itu adalah pernyataan. Dalam skrip normal, nilainya akan dibuang, tetapi di sini, kodenya harus secara internal hancur (seperti membungkus seluruh pernyataan dengan konteks fungsi dan
return
pernyataan), yang menyebabkan segala macam efek aneh, termasuk masalah yang Anda alami.Ini juga salah satu alasan mengapa beberapa kode ES6 telanjang dalam skrip berfungsi dengan baik tetapi tidak di konsol Alat Dev Chrome.
Coba jalankan ini di Node dan konsol Chrome:
Di Node atau
<script>
tag berfungsi dengan baik, tetapi di konsol, itu memberiUncaught SyntaxError: Unexpected identifier
. Ini juga memberi Anda tautan ke sumber dalam bentukVMxxx:1
yang dapat Anda klik untuk memeriksa sumber yang dievaluasi, yang muncul sebagai:Jadi mengapa ia melakukan ini?
Jawabannya adalah perlu mengubah kode Anda menjadi ekspresi sehingga hasilnya dapat dikembalikan ke pemanggil dan ditampilkan di konsol. Anda dapat melakukan ini dengan membungkus pernyataan dalam tanda kurung, yang membuatnya menjadi ekspresi, tetapi juga membuat blok di atas secara sintaksis salah (ekspresi tidak dapat memiliki deklarasi blok).
Konsol mencoba memperbaiki kasus tepi ini dengan menjadi pandai tentang kode, tapi itu di luar cakupan jawaban ini, saya pikir. Anda dapat mengajukan bug untuk melihat apakah itu sesuatu yang mereka pertimbangkan untuk memperbaikinya.
Berikut ini contoh bagus dari sesuatu yang sangat mirip:
https://stackoverflow.com/a/28431346/46588
Cara paling aman untuk membuat kode Anda berfungsi adalah memastikan kode itu dapat dijalankan sebagai ekspresi dan memeriksa
SyntaxError
tautan sumber untuk melihat apa kode eksekusi yang sebenarnya dan merekayasa balik solusi dari itu. Biasanya itu berarti sepasang kurung yang ditempatkan secara strategis.Singkatnya: konsol mencoba untuk meniru konteks eksekusi global seakurat mungkin, tetapi karena keterbatasan interaksi dengan mesin v8 dan semantik JavaScript, terkadang ini sulit atau tidak mungkin untuk dipecahkan.
sumber
Saya mengajukan pertanyaan seperti ini:
dan ini adalah jawaban Kyle Simpson:
vs.
- getify (@getify) 12 Juni 2020
sumber
console.log(x)(4)
.