JS là 1 ngôn ngữ lập trình thú vị nhất mình từng biết. Cùng với python, mình nghĩ đây 2 NNLT hay nhất mà ai cũng nên học.
Xem ví dụ sau, cho x bằng:
> x=[0]
< [0]
Thử so sánh như thế này xem
x == x
< true
Hợp lý đấy chứ, nhưng thử phủ định xem sao :
> x == !x
< true
Vì sao, là vì toán tử ! trên js nó rất khác thường, không như đa phần các NNLT khác, toán tử ! chỉ dùng cho toán hạng là số nguyên, thì toán tử ! của x dùng cho rất nhiều thể loại, và nếu sau đó là 1 mảng thì nó sẽ trả về là true. Và, ở toán tử == thì mọi thứ sẽ ép kiểu sao cho toán hạng trái sẽ cùng kiểu toán hạng phải, lúc này x ép kiểu về boolean thì tự nhiên nó cũng là true Khá thú vị phải ko =]] Tiếp tục, so sánh
> typeof NaN
< "number"
Haha, NaN là 1 thành phần của lớp Number đấy các bạn. Và NaN chính là Number.NaN
> typeof null
< "object"
Null là 1 Object cực kỳ đặc biệt, nếu nhìn qua các thể loại NNLT khác, có thể thấy null nó là 1 thực thể khó hiểu trong vũ trụ :)) Ví dụ trên sql, muốn so sánh với null phải dùng “is” chứ không cho dùng “=”
> null instanceof Object
null == null
< false
Như vậy có thể thấy null không thể là instance của bất cứ cái gì, kể cả là chính nó =]]
> 9999999999999999
< 10000000000000000
Overload number nên làm tròn luôn :v
> 0.1 + 0.2 == 0.3
< false
Không phải chỉ mỗi javascript bị lỗi này, rất nhiều NNLT cũng bị bệnh này, là do số float khi convert qua binary để thực hiện các phép cộng trên máy, lúc convert về kết quả, nếu trình biên dịch không chịu làm tròn thì nó sẽ ra kiểu như vầy 0.1 + 0.2 = 0.30000000000000001 Như vậy nó khác 0.3 là chuẩn rồi
> Math.max()>Math.min()
< false
Toán tử > vô dụng trong TH này
> Math.max()<Math.min()
< true
Toán tử < cũng vô dụng trong TH này =]]
> []+[]
< ""
[]+{}
< "[object Object]"
{}+[]
< 0
{}+{}
< NaN
Đây chính xác là vẻ đẹp của javascript: Toán tử cộng.
> true+true===2
true-true===0
< true
Việc ép kiểu cho các phép toán boolean như === cũng rất bất ngờ :))
> "2" * "2" === 4
"2" + "2" === 4
< false
Có thể thấy toán tử cộng sẽ ưu tiên cộng chuỗi trước phép toán. Nên “2” + “2” sẽ là “22” trước.
Còn phép nhân, nó sẽ ép kiểu 2 toán hạng cho ra kiểu dữ liệu cuối cùng bị gán về.
Ở ví dụ trên, khi x === 4 thì x sẽ bị ép kiểu về integer vì toán tử === ép 2 bên về cùng 1 kiểu dữ liệu bên phải.
và “2” * “2” phải là kiểu integer, nên phép nhân ép 2 toán hạng 2 bên về integer nốt. Và thực hiện phép nhân 2 * 2 === 4 là chuẩn rồi
Tham khảo:
https://charlieharvey.org.uk/page/javascript_the_weird_parts