Javascript - the bad part (continue)
Bài đăng này đã không được cập nhật trong 8 năm
Trong bài viết lần trước, chúng ta đã được thấy 1 số "bad part" trong javacript, phần này chúng ta sẽ tiếp tục tìm hiểu về những điểm khác mà cũng gây cho developer không ít phiền toái khi lập trình với javascritp
NaN
NaN là 1 giá trị đặc biệt trong javascript, nó
có nghĩa là not a number
mặc dù khi thực hiện
phép toán để tìm kiểu của nó thì lại trả về number
typeof(NaN) === 'number'
=> true
Chúng ta có thể thu được giá trị NaN
khi chuyển
đổi 1 string không biểu diến 1 số về dạng số
+'123'
=> 123
+'123abc'
=> NaN
1 chuỗi các phép toán số học mà chứa toán tử NaN
thì
sẽ trả về NaN
1+2*3-NaN
=> NaN
Do phép toán typeof
không thể dùng để phân biệt
số thường và NaN
nên 1 điều ngạc nhiên đã xảy ra
là NaN
không bằng chính nó (yaoming)
NaN === NaN
=> false
NaN !== NaN
=> true
Vì vậy javascript cung cấp hàm isNaN
để phân biệt
NaN
với các giá trị số khác
isNaN(NaN)
=> true
isNaN(0)
=> false
isNaN('oops')
=> true
isNaN('0')
=> false
Phép toán tốt nhất để xác định 1 giá trị có phải
là số hay không có lẽ là isFinite
vì phép toán
này sẽ loại bỏ giá trị NaN
và Infinity
tuy nhiên
phép toán này lại tự ép kiểu đối số
isFinite(1)
=> true
isFinite(NaN)
=> false
isFinite(1/0)
=> false
isFinite("1")
=> true
Nếu muốn xác định chính xác 1 giá trị có phải là
số hay không bạn có thể tự định nghĩa 1 hàm isNumber
như sau
var isNumber = function isNumber(value) {
return typeof value === 'number' && isFinite(value);
}
Block-less Statements
Javascript cho phép viết các câu lệnh bên trong if, while block bằng cách tab
lùi đầu dòng mà không cần dấu ngoặc nhọn {}
. Điều đó có nghĩa là chúng ta có
thể viết câu lệnh if
dưới đây theo 1 cách khác
a = 1;
if (true) {
a = 2;
}
a;
=> 2
a = 1;
if (true)
a = 2;
a;
=> 2
Tuy nhiên cách viết này chỉ khả dụng khi chỉ có 1 câu lệnh đơn nằm trong
câu lệnh if
. Khi có nhiều hơn 1 câu lệnh, cách viết tưởng chừng trông đẹp
hơn nhờ tiết kiệm được 2 dấu ngoặc nhọn này lại có thể gây ra nhầm lẫn tai
hại
a = 1;
b = 2;
if (false) {
a = 3;
b = 4;
}
[a, b]
=> [1, 2]
a = 1;
b = 2;
if (false)
a = 3;
b = 4;
[a, b]
=> [1, 4]
Rõ ràng kết quả của 2 cách viết trên là khác nhau và trên thực tế cách viết thứ 2 sẽ tương đương với cách viết sau đây:
a = 1;
b = 2;
if (false) {
a = 3;
}
b = 4;
[a, b]
=> [1, 4]
Vì vậy để đảm bảo không bị nhầm lẫn, tốt nhất là nên viết đầy đủ dấu ngoặc =))
Array
Javascript không có mảng thực sự. Chúng ta có thể khai báo 1 mảng trong javascript mà không cần khai báo kích cỡ của nó. Điều này thuận tiện cho việc khai báo và chúng ta cũng không cần lo lắng về lỗi tràn mảng khi truy cập 1 phần tử có index vượt quá kích cỡ mảng. Tuy nhiên do không có mảng thực sự nên hiệu năng của nó sẽ kém đi.
Việc xác định 1 đối tượng có phải là mảng hay không cũng khá rắc rối khi
câu lệnh typeof lại trả về "object"
thay vì "array"
.
a = [1, 2];
typeof(a);
=> "object"
Để xác định 1 đối tượng có phải là mảng hay không ta phải xem xét đến constructor
của đối tượng đó
a = [1, 2];
if (a && typeof a === 'object' && a.constructor === Array) {
"a is an array!"
}
=> "a is an array!"
All rights reserved