Ayo Main Sedikit Lagi!
Pertama, mari bersenang-senang !:
//----------#01#-----------
{}[true]; //[true]
//----------#02#-----------
var a = {}[true];
console.log(a); //undefined
//----------#03#-----------
{ b: 12345 }[true]; //[true]
//----------#04#-----------
{ b: 12345 }["b"]; //evaluates to ["b"] ?!?
//----------#05#-----------
{ b: 12345 }.b; // "Unexpected token ."
//----------#06#-----------
({ b: 12345 }).b; //12345
//----------#07#-----------
var c = { b: 12345 }.b;
console.log(c); //12345
//----------#08#-----------
var c = { b: 12345 }["b"];
console.log(c); //12345
//----------#09#-----------
{ true: 54321 }[true]; // "SyntaxError: Unexpected token : "
//----------#10#-----------
var d = { true: 54321 }[true]; //No error here ¬¬
console.log(d); //54321
//----------#11#-----------
!{}[true]; // true
Ok, mari kita coba memahami perilaku gila ini, satu per satu:
1) Di sini, {}diuraikan sebagai blok kode kosong. Tanpa penetapan, negasi, pengelompokan (dengan tanda kurung) atau sintaks apa pun yang menunjukkan kepada parser bahwa ini {}adalah objek literal, asumsi default adalah menganggapnya hanyalah blok kosong yang tidak berguna.
Ini adalah bukti dari perilaku ini:
{ alert(123) }[true]
Kode di atas akan menampilkan peringatan itu secara normal, dan akan dievaluasi seperti [true]halnya dengan cara yang sama {}[true].
Blokir Pernyataan Tanpa Titik Koma
Pernyataan tipe blok tidak perlu titik koma setelahnya.
Misalnya:
for(var i=0; i < 1; i++){}function a(){};alert("Passed here!");if(true){}alert("Passed here too!")
Kedua peringatan ditampilkan.
Jadi, kita dapat melihat bahwa pernyataan blok kosong, tanpa titik koma, valid dan tidak melakukan apa-apa. Dengan cara ini, ketika Anda memasukkan {}[true]di Konsol Alat Pengembang (atau Firebug), nilai yang dievaluasi akan menjadi nilai pernyataan ekspresi terakhir . Dalam hal ini, pernyataan ekspresi terakhir adalah [true].
2) Dalam konteks penugasan, parser akan memastikan bahwa itu {}adalah objek literal. Ketika Anda melakukan var a = {}[true], Anda menghapus ambiguitas dan memberi tip parser yang {}bukan pernyataan blok.
Jadi, di sini, Anda mencoba untuk mendapatkan nilai dengan kunci "true"dari objek kosong. Jelas, tidak ada pasangan nilai kunci dengan nama kunci ini. Dengan cara ini, variabel tidak terdefinisi.
Kata-kata yang dicadangkan sebagai kunci Objek
ECMAScript 5 memungkinkan kunci objek untuk dilindungi undang-undang. Jadi, kunci-kunci berikut ini legal:
var obj = {if: 111, for: 222, switch: 333, function: 444, true: 555}
3) Penjelasan yang sama dari contoh 1 . Tapi ... Jika { b: 12345 }bagian itu diperlakukan sebagai pernyataan blok, apa jenis b: 12345pernyataannya ??
... (?????)
Ini pernyataan label , Anda sudah melihatnya sebelumnya ... Ini digunakan dalam loop dan in switch. Berikut adalah beberapa tautan menarik tentang pernyataan label: 1 , (2) [ Cara terbaik untuk melepaskan diri dari loop bersarang di Javascript? , (3) [ Bagaimana cara memecah loop bersarang di javascript? .
CATATAN: Coba saja evaluasi ini:
{a: 1, b: 2} //=>>>SyntaxError: Unexpected token :
Pernyataan label tidak dapat dipisahkan oleh operator koma , Anda harus memisahkannya dengan tanda titik koma. Jadi ini valid:{a: 1; b: 2}
4) Lihat penjelasan untuk contoh 1 dan 3 ...
5) Sekali lagi, kami { b: 12345 }diperlakukan sebagai blok kode, dan Anda mencoba mengakses properti blok kode dengan menggunakan notasi titik , dan jelas, ini tidak diizinkan, dan parser melempar "Unexpected token :"pengecualian.
6) Kode hampir identik dengan contoh di atas, tetapi dengan mengelilingi { b: 12345 }pernyataan dengan operator pengelompokan ekspresi , parser akan tahu bahwa itu adalah objek. Dengan cara ini, Anda dapat mengakses "b"properti secara normal.
7) Ingat contoh 2 , kami punya tugas di sini, parser tahu itu { b: 12345 }adalah objek.
8) Identik dengan contoh di atas, tetapi alih-alih notasi titik, di sini kita menggunakan notasi braket .
9) Saya sudah mengatakan bahwa "identifier: value"sintaks ini di dalam pernyataan blok adalah label. Tapi, Anda juga harus tahu bahwa nama label tidak boleh kata kunci yang dipesan (kebalikan dari nama properti objek). Ketika kami mencoba mendefinisikan label yang disebut "true", kami mendapat a SyntaxError.
10) Sekali lagi, kita berurusan dengan suatu objek. Tidak ada masalah menggunakan kata-kata yang dipesan di sini. =)
11) Akhirnya, kami memiliki ini:!{}[true]
Mari kita pisahkan hal-hal di sini:
a) Dengan melakukan negasi, kami memberi tahu parser bahwa objek {}adalah objek .
b) Seperti yang ditunjukkan pada contoh 2 , {}objek tidak memiliki properti yang dipanggil true, jadi ungkapan ini akan dievaluasi undefined.
c) Hasil akhirnya adalah negasi undefinednilai. Javascript melakukan konversi tipe implikasi , dan undefinednilainya falsy .
d) Jadi, negasi dari falseadalah ... true!
var o = {}; o[true] === undefined.