var a = {}
var b = {}
try{
a.x.y = b.e = 1 // Uncaught TypeError: Cannot set property 'y' of undefined
} catch(err) {
console.error(err);
}
console.log(b.e) // 1
var a = {}
var b = {}
try {
a.x.y.z = b.e = 1 // Uncaught TypeError: Cannot read property 'y' of undefined
} catch(err) {
console.error(err);
}
console.log(b.e) // undefined
javascript
operators
order-of-execution
Kevin Askin
sumber
sumber
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?y
tidak ada dia.x
; tapi itu benar dalam kedua kasus. Mengapa ini mencegah penugasan sisi kanan dalam kasus kedua tetapi tidak yang pertama? Apa yang berbeda dalam urutan eksekusi? (Saya menyebutkan kesalahan sintaks karena waktu pada kesalahan sintaks sangat berbeda dari kesalahan runtime.)Jawaban:
Sebenarnya, jika Anda membaca pesan kesalahan dengan benar, kasus 1 dan kasus 2 menimbulkan kesalahan yang berbeda.
Kasus
a.x.y
:Kasus
a.x.y.z
:Saya rasa yang terbaik adalah mendeskripsikannya dengan eksekusi langkah demi langkah dalam bahasa Inggris yang mudah.
Kasus 1
Kasus 2
Dalam komentar, Solomon Tam menemukan dokumentasi ECMA ini tentang operasi penugasan .
sumber
Urutan operasi lebih jelas saat Anda mengeksploitasi operator koma di dalam tanda kurung siku untuk melihat bagian mana yang dieksekusi ketika:
Melihat speknya :
PutValue
adalah apa yang melemparTypeError
:Tidak ada yang dapat ditetapkan ke properti
undefined
-[[CanPut]]
metode internalundefined
akan selalu kembalifalse
.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
Sisi kiri berhasil diurai hingga
PutValue
dipanggil; fakta bahwa.x
properti mengevaluasi keundefined
tidak dipertimbangkan sampai sisi kanan diuraikan. Penerjemah melihatnya sebagai "Tetapkan beberapa nilai ke properti" y "dari tidak terdefinisi", dan menetapkan ke propertiundefined
hanya lemparan ke dalamPutValue
.Sebaliknya:
Penerjemah tidak pernah sampai pada titik di mana ia mencoba untuk menetapkan ke
z
properti, karena ia harus menetapkan nilai terlebih dahulua.x.y
. Jikaa.x.y
diselesaikan menjadi nilai (bahkan sampaiundefined
), itu akan baik-baik saja - kesalahan akan dilemparkan ke dalamPutValue
seperti di atas. Tetapi mengaksesa.x.y
melontarkan kesalahan, karena propertiy
tidak dapat diaksesundefined
.sumber
Perhatikan kode berikut:
Garis besar langkah-langkah kasar yang diperlukan untuk mengeksekusi kode adalah sebagai berikut ref :
a.x.y
mengembalikan referensi ref terdiri dari nilai dasara.x
(terdefinisi) dan nama direferensikan (y
).y
tidak terdefinisi ke nilai. Ini seharusnya memunculkan ref pengecualian TypeError .sumber