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)
.
PutValue
atan ş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 undefined
her 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 undefined
yalnı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.y
bir 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ı PutValue
yukarıda gibi. Ancak erişim a.x.y
, özelliğe y
erişim sağlanamadığı için bir hata verir undefined
.
b.z = 1
veb.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 ; Nedenb
bir durumda atama geçiyor, diğerinde değil?