Có thể nào (a==1 && a==2 && a==3) trả về 'true' trong JavaScript?
Gần đây, một đoạn mã JavaScript thú vị đã thu hút sự chú ý trên mạng xã hội X (Twitter) và Reddit. Câu hỏi đặt ra là: Liệu biểu thức (a==1 && a==2 && a==3) có bao giờ trả về giá trị 'true' không? Câu trả lời là - Có! Chúng ta hãy cùng khám phá lý do tại sao điều này có thể xảy ra.
javascript
const a = {
num: 0,
valueOf: function() {
return this.num += 1;
}
};
const equality = (a==1 && a==2 && a==3);
console.log(equality); // true
Nếu bạn đang sử dụng Google Chrome, hãy mở bảng điều khiển (console) bằng tổ hợp phím Ctrl + Shift + J
(trên Windows) hoặc Cmd + Opt + J
(trên Mac).
Thủ thuật đằng sau đoạn mã
Sự thú vị nằm ở chỗ, không có thủ thuật phức tạp nào. Đoạn mã này tận dụng hai khái niệm cơ bản trong JavaScript:
- So sánh không nghiêm ngặt (loose equality)
- Phương thức
valueOf()
của đối tượng
Biểu thức (a==1 && a==2 && a==3) sử dụng toán tử so sánh không nghiêm ngặt ==
. Điều này có nghĩa là JavaScript sẽ thực hiện chuyển đổi kiểu dữ liệu (type coercion), tự động chuyển đổi kiểu dữ liệu để so sánh.
Cách thức hoạt động
Phương thức valueOf()
của đối tượng a
tăng giá trị thuộc tính num
lên 1 mỗi khi nó được gọi. Khi thực hiện so sánh giữa a
và các số, JavaScript sẽ gọi phương thức valueOf()
để chuyển a
thành một số trước khi so sánh.
Dưới đây là cách từng phần của biểu thức hoạt động:
a == 1
gọia.valueOf()
, trả về0 + 1 == 1
✅a == 2
gọia.valueOf()
, trả về1 + 1 == 2
✅a == 3
gọia.valueOf()
, trả về2 + 1 == 3
✅
Kết quả cuối cùng là biểu thức (a==1 && a==2 && a==3) trả về giá trị 'true'.
Lời kết
Mặc dù đây là một thủ thuật thú vị, nhưng trong thực tế, chúng ta hiếm khi viết mã như vậy. Tuy nhiên, câu hỏi này nhấn mạnh sự quan trọng của việc hiểu sâu ngôn ngữ lập trình và cách nó hoạt động. Hi vọng rằng bài viết này đã giúp bạn làm rõ khái niệm về so sánh không nghiêm ngặt và phương thức valueOf() trong JavaScript. Hãy tiếp tục khám phá và không ngừng học hỏi!
source: viblo