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 = AssignmentExpressiondievaluasi 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).
PutValueadalah 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 undefinedakan 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 PutValuedipanggil; fakta bahwa .xproperti mengevaluasi ke undefinedtidak dipertimbangkan sampai sisi kanan diuraikan. Penerjemah melihatnya sebagai "Tetapkan beberapa nilai ke properti" y "dari tidak terdefinisi", dan menetapkan ke properti undefinedhanya 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 zproperti, karena ia harus menetapkan nilai terlebih dahulu a.x.y. Jika a.x.ydiselesaikan menjadi nilai (bahkan sampai undefined), itu akan baik-baik saja - kesalahan akan dilemparkan ke dalam PutValueseperti di atas. Tetapi mengakses a.x.y melontarkan kesalahan, karena properti ytidak dapat diakses undefined.
b.z = 1danb.e = 1mengeksekusi pertama (mengingat asosiatif kanan=), lalua.x.y.z = ...mengeksekusi dan gagal; mengapabtugas lulus dalam satu kasus tetapi tidak di kasus lain?