Thứ tự của các hoạt động rõ ràng hơn khi bạn khai thác toán tử dấu phẩy bên trong ký hiệu dấu ngoặc để xem phần nào được thực thi khi:
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
Nhìn vào thông số kỹ thuật :
Việc sản xuất AssignmentExpression : LeftHandSideExpression = AssignmentExpression
được đánh giá như sau:
Gọi lref là kết quả đánh giá LeftHandSideExpression.
Gọi rref là kết quả đánh giá AssignmentExpression.
Hãy để rval là GetValue(rref)
.
Ném một ngoại lệ SyntaxError nếu ... (không liên quan)
Gọi điện PutValue(lref, rval)
.
PutValue
là những gì ném TypeError
:
Hãy để O được ToObject(base)
.
Nếu kết quả của việc gọi [[CanPut]]
phương thức bên trong của O với đối số P là sai, thì
a. Nếu Throw là true, thì hãy ném một ngoại lệ TypeError.
Không có gì có thể được gán cho thuộc tính của undefined
- [[CanPut]]
phương thức nội bộ của undefined
sẽ luôn trả về false
.
Nói cách khác: trình thông dịch phân tích cú pháp phía bên trái, sau đó phân tích cú pháp phía bên phải, sau đó đưa ra lỗi nếu không thể gán thuộc tính ở phía bên trái.
Khi bạn làm
a.x.y = b.e = 1
Phía bên tay trái được phân tích cú pháp thành công cho đến khi PutValue
được gọi; thực tế mà thuộc .x
tính đánh giá undefined
sẽ không được xem xét cho đến khi phần bên phải được phân tích cú pháp. Trình thông dịch coi nó là "Gán một số giá trị cho thuộc tính" y "của undefined" và gán cho thuộc tính undefined
chỉ ném bên trong PutValue
.
Ngược lại:
a.x.y.z = b.e = 1
Trình thông dịch không bao giờ đạt đến điểm mà nó cố gắng gán cho thuộc z
tính, vì trước tiên nó phải phân giải a.x.y
thành một giá trị. Nếu a.x.y
được giải quyết thành một giá trị (thậm chí thành undefined
), nó sẽ không sao - một lỗi sẽ được đưa vào bên trong PutValue
như trên. Nhưng việc truy cập a.x.y
sẽ gặp lỗi, vì y
không thể truy cập thuộc tính vào undefined
.
b.z = 1
vàb.e = 1
thực hiện trước (đã cho tính liên kết phải trên=
), sau đóa.x.y.z = ...
thực thi và không thành công; tại saob
chuyển nhượng được chuyển trong một trường hợp mà không phải trong trường hợp khác?