Biraz Daha Oynayalım!
İlk önce biraz eğlenelim !:
//----------#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
Tamam, bu çılgın davranışları birer birer anlamaya çalışalım:
1) Burada, {}boş bir kod bloğu olarak ayrıştırılır. Bir atama, olumsuzlama, gruplama (parantezlerle) veya ayrıştırıcıya bunun {}bir nesne değişmezi olduğunu belirten herhangi bir sözdizimi olmadan , varsayılan varsayım, bunun sadece işe yaramaz bir boş blok olduğunu düşünmektir.
Bu, bu davranışın bir kanıtıdır:
{ alert(123) }[true]
Yukarıdaki kod normal uyarı gösterir ve şekilde değerlendirilecektir [true]Aynı şekilde, {}[true]bir.
Noktalı Virgül İçermeyen Blok İfadeleri
Blok tipi bir ifadeden sonra noktalı virgül gerekmez.
Örneğin:
for(var i=0; i < 1; i++){}function a(){};alert("Passed here!");if(true){}alert("Passed here too!")
Her iki uyarı da gösterilir.
Böylece, noktalı virgül içermeyen boş bir blok ifadesinin geçerli olduğunu ve hiçbir şey yapmadığını görebiliriz. Bu şekilde, {}[true]Geliştirici Araçları (veya Firebug) Konsoluna girdiğinizde , değerlendirilen değer, son ifade ifadesinin değeri olacaktır . Bu durumda, son ifade ifadesi [true].
2) Bir atama bağlamında, ayrıştırıcı bunun {}bir nesne değişmezi olduğundan emin olacaktır . Var a = yaptığınızda {}[true], herhangi bir belirsizliği kaldırırsınız ve {}bir blok ifadesi olmayan ayrıştırıcıyı devre dışı bırakırsınız .
Yani burada, "true"boş bir nesneden anahtarla bir değer elde etmeye çalışıyorsunuz . Açıkçası, bu anahtar adına sahip bir anahtar / değer çifti yoktur. Bu şekilde, a değişkeni tanımsızdır.
Nesne anahtarları olarak ayrılmış kelimeler
ECMAScript 5 , nesne anahtarlarının ayrılmış sözcükler olmasına izin verir. Dolayısıyla, aşağıdaki anahtarlar yasaldır:
var obj = {if: 111, for: 222, switch: 333, function: 444, true: 555}
3) Örnek 1'in aynı açıklaması . Ama ... { b: 12345 }Parça bir blok deyimi olarak değerlendirilirse, ifadenin türü nedir b: 12345?
... (?????)
Bu bir etiket ifadesi , daha önce görmüştünüz ... Döngülerde ve içinde kullanılıyor switch. Etiket ifadeleriyle ilgili birkaç ilginç bağlantı şunlardır: 1 , (2) [ Javascript'teki iç içe döngülerden kurtulmanın en iyi yolu? , (3) [ JavaScript'te iç içe döngüler nasıl kırılır? .
NOT: Bunu değerlendirmeye çalışın:
{a: 1, b: 2} //=>>>SyntaxError: Unexpected token :
Etiket ifadeleri virgül operatörüyle ayrılamaz, bunları bir noktalı virgülle ayırmanız gerekir. Yani bu geçerli:{a: 1; b: 2}
4) Örnek 1 ve 3 için açıklamalara bakınız ...
5) Bir kez daha, { b: 12345 }bir kod bloğu muamelesi gören bir varlığımız var ve nokta gösterimini kullanarak bir kod bloğunun bir özelliğine erişmeye çalışıyorsunuz ve tabii ki buna izin verilmiyor ve ayrıştırıcı bir "Unexpected token :"istisna atıyor .
6) Kod yukarıdaki örnekle hemen hemen aynıdır, ancak ifadeyi ifade gruplama operatörü{ b: 12345 } ile çevreleyerek ayrıştırıcı bunun bir nesne olduğunu bilecektir. Bu şekilde, mülke normal olarak erişebileceksiniz ."b"
7) Örnek 2'yi hatırlayın, burada bir atamamız var, ayrıştırıcı bunun { b: 12345 }bir nesne olduğunu biliyor .
8) Yukarıdaki örnekle aynıdır, ancak nokta notasyonu yerine burada köşeli parantez gösterimini kullanıyoruz .
9)"identifier: value" Bir blok ifadesinin içindeki bu sözdiziminin bir etiket olduğunu söylemiştim . Ancak, bir etiket adının ayrılmış bir anahtar kelime olamayacağını da bilmeniz gerekir (nesne özellik adlarının tersi). Adlı bir etiketi tanımlamaya çalıştığımızda "true", bir SyntaxError.
10) Yine, bir nesneyle uğraşıyoruz. Burada ayrılmış kelimeleri kullanmakta sorun yok. =)
11) Son olarak, şuna sahibiz:!{}[true]
Buradaki şeyleri ayıralım:
a) olumsuzlamasıydı yaparak, bu ayrıştırıcı bilgisini veriyoruz {}olan bir nesne .
b) Örnek 2'de gösterildiği gibi , bir {}nesnenin adı verilen bir özelliği yoktur true, bu nedenle bu ifade olarak değerlendirilecektir undefined.
c) Nihai sonuç, undefineddeğerin olumsuzlanmasıdır . Javascript , implicity türü dönüşümü gerçekleştirir ve undefineddeğer yanlıştır .
d) Yani, olumsuzlama false... true!
var o = {}; o[true] === undefined.