Urutan operasi lebih jelas saat Anda mengeksploitasi operator koma di dalam tanda kurung siku untuk melihat bagian mana yang dieksekusi ketika:
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
Melihat speknya :
Produksi AssignmentExpression : LeftHandSideExpression = AssignmentExpression
dievaluasi sebagai berikut:
Misalkan lref menjadi hasil evaluasi LeftHandSideExpression.
Misalkan rref adalah hasil evaluasi AssignmentExpression.
Biarkan rval menjadi GetValue(rref)
.
Lemparkan pengecualian SyntaxError jika ... (tidak relevan)
Panggil PutValue(lref, rval)
.
PutValue
adalah apa yang melempar TypeError
:
Biarkan O menjadi ToObject(base)
.
Jika hasil pemanggilan [[CanPut]]
metode internal O dengan argumen P salah, maka
Sebuah. Jika Throw benar, maka lemparkan pengecualian TypeError.
Tidak ada yang dapat ditetapkan ke properti undefined
- [[CanPut]]
metode internal undefined
akan selalu kembali false
.
Dengan kata lain: interpreter mengurai sisi kiri, lalu mengurai sisi kanan, lalu melontarkan kesalahan jika properti di sisi kiri tidak dapat ditetapkan.
Saat kamu melakukan
a.x.y = b.e = 1
Sisi kiri berhasil diurai hingga PutValue
dipanggil; fakta bahwa .x
properti mengevaluasi ke undefined
tidak dipertimbangkan sampai sisi kanan diuraikan. Penerjemah melihatnya sebagai "Tetapkan beberapa nilai ke properti" y "dari tidak terdefinisi", dan menetapkan ke properti undefined
hanya lemparan ke dalam PutValue
.
Sebaliknya:
a.x.y.z = b.e = 1
Penerjemah tidak pernah sampai pada titik di mana ia mencoba untuk menetapkan ke z
properti, karena ia harus menetapkan nilai terlebih dahulu a.x.y
. Jika a.x.y
diselesaikan menjadi nilai (bahkan sampai undefined
), itu akan baik-baik saja - kesalahan akan dilemparkan ke dalam PutValue
seperti di atas. Tetapi mengakses a.x.y
melontarkan kesalahan, karena properti y
tidak dapat diakses undefined
.
b.z = 1
danb.e = 1
mengeksekusi pertama (mengingat asosiatif kanan=
), lalua.x.y.z = ...
mengeksekusi dan gagal; mengapab
tugas lulus dalam satu kasus tetapi tidak di kasus lain?