ลำดับของการดำเนินการจะชัดเจนขึ้นเมื่อคุณใช้ตัวดำเนินการลูกน้ำภายในสัญกรณ์วงเล็บเพื่อดูว่าส่วนใดถูกดำเนินการเมื่อ:
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
ดูข้อมูลจำเพาะ :
การผลิตAssignmentExpression : LeftHandSideExpression = AssignmentExpressionได้รับการประเมินดังนี้:
ให้ lref เป็นผลลัพธ์ของการประเมิน LeftHandSideExpression
ให้ rref เป็นผลลัพธ์ของการประเมิน AssignmentExpression
GetValue(rref)อนุญาตเป็น rval
โยนข้อยกเว้น SyntaxError ถ้า ... (ไม่เกี่ยวข้อง)
โทรPutValue(lref, rval).
PutValueคือสิ่งที่พ่นTypeError:
ToObject(base)ให้เป็น O
หากผลลัพธ์ของการเรียก[[CanPut]]เมธอดภายในของ O ด้วยอาร์กิวเมนต์ P เป็นเท็จดังนั้น
ก. ถ้า Throw เป็นจริงให้โยนข้อยกเว้น TypeError
ไม่มีอะไรที่สามารถกำหนดให้กับทรัพย์สินของundefined- The [[CanPut]]วิธีการภายในของมักจะกลับมาundefinedfalse
กล่าวอีกนัยหนึ่ง: ล่ามจะแยกวิเคราะห์ทางด้านซ้ายจากนั้นแยกวิเคราะห์ทางด้านขวาจากนั้นจะแสดงข้อผิดพลาดหากไม่สามารถกำหนดคุณสมบัติทางด้านซ้ายมือให้ได้
เมื่อคุณทำ
a.x.y = b.e = 1
ด้านซ้ายมือจะถูกแยกวิเคราะห์เรียบร้อยแล้วจนกว่าPutValueจะถูกเรียก ความจริงที่ว่า.xคุณสมบัติที่ประเมินundefinedเป็นจะไม่ได้รับการพิจารณาจนกว่าจะมีการแยกวิเคราะห์ด้านขวามือ ล่ามจะมองว่าเป็น "กำหนดค่าบางอย่างให้กับคุณสมบัติ" y "ของไม่ได้กำหนด" และกำหนดให้กับคุณสมบัติที่undefinedโยนเข้าไปข้างในPutValueเท่านั้น
ในทางตรงกันข้าม:
a.x.y.z = b.e = 1
ล่ามจะไม่ไปถึงจุดที่พยายามกำหนดให้กับzคุณสมบัติเพราะต้องแก้ไขa.x.yเป็นค่าก่อน หากa.x.yแก้ไขเป็นค่า (แม้ถึงundefined) ก็จะใช้ได้ - ข้อผิดพลาดจะถูกโยนเข้าไปข้างในPutValueเหมือนข้างบน แต่การเข้าถึง a.x.yโยนข้อผิดพลาดเพราะคุณสมบัติที่ไม่สามารถเข้าถึงได้บนyundefined
b.z = 1และb.e = 1ดำเนินการก่อน (ให้สิทธิ์การเชื่อมโยงบน=) จากนั้นa.x.y.z = ...ดำเนินการและล้มเหลว เหตุใดการbมอบหมายจึงส่งผ่านในกรณีหนึ่ง แต่ไม่ผ่านอีกกรณีหนึ่ง