Saya perhatikan hari ini bahwa Chrome 49 tidak lagi menghasilkan NaN
ketika Anda mengetik {}+{}
ke konsol. Sebaliknya itu menghasilkan string [object Object][object Object]
.
Kenapa ini? Apakah bahasanya berubah?
Saya perhatikan hari ini bahwa Chrome 49 tidak lagi menghasilkan NaN
ketika Anda mengetik {}+{}
ke konsol. Sebaliknya itu menghasilkan string [object Object][object Object]
.
Kenapa ini? Apakah bahasanya berubah?
Jawaban:
Chrome devtools sekarang secara otomatis membungkus segala sesuatu yang dimulai dengan {
dan diakhiri dengan }
sepasang kurung implisit ( lihat kode ), untuk memaksa evaluasinya sebagai sebuah ekspresi. Dengan begitu, {}
buat objek kosong sekarang. Anda dapat melihat ini jika Anda kembali melalui histori ( ↑), baris sebelumnya akan terkandung dalam (…)
.
Mengapa? Saya tidak tahu, tapi saya bisa menebak itu mengurangi kebingungan untuk pemula yang tidak tahu tentang hal block-vs-object-literal, dan itu juga lebih membantu jika Anda hanya ingin mengevaluasi ekspresi.
Dan sebenarnya itulah alasannya, seperti yang dibahas dalam bug 499864 . Kenyamanan murni. Dan karena simpul REPL memilikinya juga ( lihat kode ).
{a:1}),({b:2}
harus melempar kesalahan, tidak menghasilkan objek.
)
jika ada dalam komentar, misalnya {a:3} // :-}
mungkin masih menghasilkan objek.
Jika Anda menekan panah ke atas setelah memeriksa ini, Anda akan melihat bahwa alih-alih {} + {}
itu ditampilkan ({} + {})
, yang menghasilkan "[object Object][object Object]"
.
Sebagai perbandingan, di Firefox, {} + {}
masih menampilkan NaN
, tetapi jika Anda melakukannya ({} + {})
juga menampilkan "[object Object][object Object]"
.
Jadi, sepertinya Chrome menambahkan tanda kurung di sekitarnya secara otomatis ketika melihat operasi ini.
{} + {}
ketika tidak "disanitasi" untuk ({} + {})
diperlakukan sebagai + {}
karena {}
diurai sebagai blok kosong.
{}
hanya blok kode kosong dan diabaikan, meninggalkan kita dengan +{}
, yang merupakan objek unary +
dan kosong penginisialisasi. +
akan memaksa argumennya ke angka, yang melibatkan konversi objek ke primitif (yang akhirnya akan menjadi toString
dalam kasus ini, menghasilkan "[object Object]"
), dan kami mendapatkan +"[object Object]"
yang NaN
karena "[object Object]"
tidak dapat dikonversi ke nomor yang valid.
Sayangnya, saya menambahkan kutipan Clippy sendiri. Konsol tidak memberikan informasi tentang apa yang telah dilakukan untuk Anda.
Aturan baru ini sangat sederhana, menyelamatkan kita dari kesulitan mengetik 2 karakter sulit ini o=
atau 0,
sebelum menempelkan Object Literals ke konsol:
{
;{wat:1}),({wat:2}
Akhirnya kesalahan lagi.
{let i=0;var increment=_=>i++}
akhirnya diizinkan dengan benar, yang merupakan cara yang cukup baik untuk melakukan penutupan.
Namun, berikut ini adalah objek yang salah, ini hanya sebagai kenyamanan seperti yang disebutkan oleh @Bergi, itu menafsirkan JS salah untuk membantu Anda! Spec mengatakan itu adalah blok dengan pernyataan berlabel "foo" dengan 1 literal yang tidak ditugaskan untuk apa pun.
{foo:1}
Di atas harus sama dengan
if(1) {
foo: 1
}
Berikut ini diperlakukan dengan benar sebagai blok ... karena memiliki komentar di depannya!
//magic comment
{foo:1}
Begitu juga ini:
{foo:1}
//also magic
Ini adalah sebuah Objek:
{foo:
//not so magic comment
1}
Ini adalah kesalahan
//not so magic comment
{foo:1}.foo
Begitu juga ini:
{foo:1}.foo
Ini baik:
1..wat
undefined
begitu juga ini:
['foo'][0]
Yang berikutnya ditafsirkan dengan benar sebagai objek yang dipukul ke posisi ekspresi dengan 0,
yang umumnya bagaimana kita memastikan kita memiliki ekspresi bukannya pernyataan.
0,{foo:1}.foo
Saya tidak mengerti mengapa mereka membungkus nilai dalam parens. JS memiliki beberapa keputusan desain yang konyol, tetapi mencoba membuatnya berperilaku lebih baik dalam situasi yang satu ini sebenarnya bukan pilihan, konsol perlu menjalankan JS dengan benar, dan kita perlu yakin bahwa chrome tidak hanya menebak bahwa menurutnya kita berpikir benar-benar bermaksud melakukan sesuatu yang lain.
Jika Anda tidak menyukai operator koma, Anda dapat menggunakan penugasan
x = {foo:1}.foo
Karena sebagaimana adanya
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
Gila dan konsisten saya bisa berurusan dengan ... gila dan tidak konsisten tidak, terima kasih!
{foo:1}
dan {foo:1}//
menghasilkan hal yang sama. Di Chrome JS REPL mereka tidak. REPL melakukan lebih dari sekadar mengevaluasi JS. Ini memproses string dan memutuskan untuk hal-hal yang berbeda.
var x = eval('{a:1}')
Dalam JavaScript x yang valid sekarang 1, bukan objek yang lebih intuitif {a: 1}. Ya, itu aneh, tetapi Anda tidak bisa hanya mengubah bahasa karena melakukan hal-hal aneh. Segala sesuatu selain string JSON ditafsirkan sebagai JavaScript dan dievaluasi. Mengetik 0,
sebelum menempelkan JSON tidak sulit, atau saya akan senang dengan peringatan bahwa string ditafsirkan sebagai objek, bukan JavaScript untuk kenyamanan.
var e = {}; e.toString()
dan Anda akan melihat apa yang saya maksud