Aşağıdaki durumlarda hangi parçaların yürütüldüğünü görmek için köşeli parantez içinde virgül operatörünü kullandığınızda işlem sırası daha nettir:
var a = {}
var b = {}
try{
// Uncaught TypeError: Cannot set property 'y' of undefined
a
[console.log('x'), 'x']
[console.log('y'), 'y']
= (console.log('right hand side'), b.e = 1);
} catch(err) {
console.error(err);
}
console.log(b.e) // 1
var a = {}
var b = {}
try {
// Uncaught TypeError: Cannot read property 'y' of undefined
a
[console.log('x'), 'x']
[console.log('y'), 'y']
[console.log('z'), 'z']
= (console.log('right hand side'), b.e = 1);
} catch(err) {
console.error(err);
}
console.log(b.e) // undefined
Spesifikasyona bakıldığında :
Üretim AssignmentExpression : LeftHandSideExpression = AssignmentExpressionşu şekilde değerlendirilir:
Lref, LeftHandSideExpression'u değerlendirmenin sonucu olsun.
Rref, AssignmentExpression'u değerlendirmenin sonucu olsun.
Rval olsun GetValue(rref).
SyntaxError istisnası at, eğer ... (ilgisiz)
Çağrı PutValue(lref, rval).
PutValueatan şey TypeError:
O olsun ToObject(base).
[[CanPut]]O'nun dahili yöntemini P bağımsız değişkeniyle çağırmanın sonucu yanlışsa, o zaman
a. Throw doğruysa, bir TypeError istisnası atın.
Bir özelliğine hiçbir şey atanamaz undefined- [[CanPut]]iç yöntemi undefinedher zaman dönecektir false.
Başka bir deyişle: yorumlayıcı sol tarafı ayrıştırır, ardından sağ tarafı ayrıştırır, ardından sol taraftaki özellik atanamazsa bir hata atar.
Ne zaman yaparsan
a.x.y = b.e = 1
Sol taraf , çağrılana kadar başarıyla ayrıştırılırPutValue ; .xözelliğin olarak değerlendirildiği gerçeği undefined, sağ taraf çözümlenene kadar dikkate alınmaz. Yorumlayıcı bunu "tanımsız" y "özelliğine bir değer ata" olarak görür ve undefinedyalnızca içeriye atılan bir özelliği atar PutValue.
Tersine:
a.x.y.z = b.e = 1
Yorumlayıcı, zözelliğe atamaya çalıştığı noktaya asla gelmez , çünkü önce a.x.ybir değere çözümlemesi gerekir . Eğer a.x.y(hatta bir değere çözüldü undefined), Tamam olurdu - bir hata içini atılmış olacağını PutValueyukarıda gibi. Ancak erişim a.x.y , özelliğe yerişim sağlanamadığı için bir hata verir undefined.
b.z = 1veb.e = 1önce çalıştırırdım (doğru ilişkisellik verildiğinde=), sonraa.x.y.z = ...çalıştırır ve başarısız olurum ; Nedenbbir durumda atama geçiyor, diğerinde değil?