Ba toán tử gộp phép logic với phép gán, và điểm chung quan trọng là chúng short-circuit — không gán thì cũng không đánh giá vế phải.
javascript
a ||= b // a || (a = b) → chỉ gán khi a FALSY
a &&= b // a && (a = b) → chỉ gán khi a TRUTHY
a ??= b // a ?? (a = b) → chỉ gán khi a là null/undefinedDùng thực tế:
javascript
// đặt mặc định — dùng ??= để không ghi đè 0 hay chuỗi rỗng
options.retries ??= 3
options.prefix ??= ''
// chỉ xử lý khi có giá trị
user.name &&= user.name.trim()
// khởi tạo lười
cache.data ??= await loadExpensive()Khác biệt quyết định giữa ||= và ??=:
javascript
let limit = 0
limit ||= 20 // 20 ← SAI, 0 là giá trị người dùng cố ý đặt
let page = 0
page ??= 20 // 0 ← ĐÚNG, chỉ thay khi null/undefinedTính short-circuit tránh được side effect không mong muốn:
javascript
obj.a ??= expensiveCall() // expensiveCall() KHÔNG chạy nếu obj.a đã có giá trịLưu ý: vì a ||= b là a || (a = b) chứ không phải a = a || b, setter của obj.prop chỉ chạy khi thật sự gán. Viết obj.prop = obj.prop || x thì lần nào cũng gọi setter, kể cả khi giá trị không đổi — với setter nặng, khác biệt này đáng kể.
Hỗ trợ: ES2021, có mặt trên mọi trình duyệt hiện đại từ 2020–2021.