Hiểu về JavaScript

0
223

Giá trị & Kiểu

Các kiểu có sẵn là:

  • string
  • number
  • boolean
  • null and undefined
  • object
  • symbol (new to ES6)

JavaScript có một biểu thức typeof có thể kiểm tra giá trị và cho
bạn biết kiểu của nó là gì.

var a;
typeof a; // "undefined"
a = "hello world";
typeof a; // "string"
a = 42;
typeof a; // "number"
a = true;
typeof a; // "boolean"
a = null;
typeof a; // "object" -- weird, bug
a = undefined;
typeof a; // "undefined"
a = { b: "c" };
typeof a; // "object"

Giá trị trả lại từ biểu thức typeof luôn là một trong sáu kiểu ở dạng giá trị string (ES6 là 7 — thêm kiểu “symbol”). Đó là, typeof “abc” trả lại “string”, không phải string.
Chú ý rằng đoạn code này, biến a giữ mọi kiểu của giá trị, và mặc dù là có bề ngoài, typeof a sẽ không hỏi “kiểu của a”, mà là “kiểu của giá trị hiện tại trong a”. Trong JS chỉ có giá trị mới có kiểu; biến chỉ đơn giản là vật chứa các giá trị đó.typeof null là một trường hợp thú vị, bởi vì nó trả sai thành “object”, trong khi bạn mong muốn nó trả “null”.
Cảnh báo: Đây là một lỗi trường kỳ của JS và dường như sẽ không bao giờ được sửa. Quá nhiều code trên web liên quan đến lỗi mà cố sửa nó thì nó sẽ tạo ra nhiều lỗi hơn.

Objects

Kiểu object đề cập đến một giá trị phức hợp mà bạn có thể lập các thuộc tính, mỗi cái đều có thể có giá trị của riêng chúng với bất kỳ kiểu nào. Đây có lẽ là một trong nhưng kiểu hữu dụng nhất trong JS.

var obj = {
a: "hello world",
b: 42,
c: true
};
obj.a; // "hello world"
obj.b; // 42
obj.c; // true
obj["a"]; // "hello world"
obj["b"]; // 42
obj["c"]; // true

Tốt hơn là xem giá trị của obj một cách trực quan:

obj

a:

“hello world”

b:

42

c:

true

Thuộc tính có thể truy cập bằng dấu chấm (vd: obj.a) hay dấu ngoặc (vd: obj[“a”]). Dấu chấm ngắn hơn và dễ đọc hơn, vì vậy nó được ưa thích hơn.

Dấu ngoặc hữu dụng nếu bạn có một tên thuộc tính có ký tự đặc biệt trong nó, obj[“hello world!”] — các thuộc tính như vậy thường được là chìa khóa khi truy cập thông qua dấu ngoặc.
Dấu ngoặc [ ] đòi hỏi phải có một biến (giải thích sau) hoặc một string nguyên bản ( được bao bởi ” .. “hoặc ‘ .. ‘).
Đương nhiên, dấu ngoặc cũng hữu dụng nếu bạn muốn tiếp cận một thuộc tính/chìa khóa nhưng tên được lưu trữ ở biến khác , như là :

var obj = {
a: "hello world",
b: 42
};
var b = "a";
obj[b]; // "hello world"
obj["b"]; // 42

 

Mảng (array)

Trong mảng là object giữ các giá trị (của bất kỳ kiểu nào) có vị trí theo chỉ số, chứ không phải theo trong một khóa/ thuộc tính được đặt tên. Ví dụ:

var arr = [
"hello world",
42,
true
];
arr[0]; // "hello world"
arr[1]; // 42
arr[2]; // true
arr.length; // 3
typeof arr; // "object"

Ghi chú: Các ngôn ngữ thường được đếm từ 0, JS cũng dùng 0 như là chỉ mục của giá trị đầu tiên trong mảng.
Để dễ hình dung về arr hãy xem hình dưới:

obj

0:

“hello world”

1:

42

2:

true

 

Hàm

Một kiểu object con khác mà bạn sẽ sử dụng trong suốt chương trình JS là hàm:

function foo() {
return 42;
}
foo.bar = "hello world";
typeof foo; // "function"
typeof foo(); // "number"
typeof foo.bar; // "string"

Một lần nữa, hàm là kiểu con của objects — typeof trả kết quả “function” để hàm ý rằng function là một kiểu chính — và có thể có các thuộc tính, nhưng bạn chỉ thường sử dụng thuộc tính đối tượng hàm trong trường hợp giới hạn (ví dụ foo.bar).

So sánh các giá trị

Có hai kiểu so sánh giá trị chính mà bạn cần thực hiện trong chương trình JS: bằng nhau và không bằng nhau. Kết quả của bất kỳ sự so sánh nào đều là boolean (true hoặc false), bất kể kiểu già trị nào được so sánh.

Sự ép buộc

Sự ép buộc xuất hiện trong 2 dạng của JavaScript: minh bạch và tiềm ẩn. Sự ép buộc minh bạch đơn giản là bạn thấy rõ ràng trong code có một sự chuyển đổi từ dạng này sang dạng khác, trong khi đó sự ép buộc tiềm ẩn là khi chuyển đổi dạng có thể xảy ra nhiều hơn, là một hiệu ứng phụ của một số hoạt động khác.
Bạn có thể từng nghe ý kiến rằng “sự ép buộc là ma quỷ” được nêu ra trong một số sự kiện tại một vị trí rõ ràng nào đó, nơi mà sự ép buộc có thể tạo nên những kết quả bỡ ngỡ. Có lẽ đối với các developer thì không có gì thất vọng hơn khi một ngôn ngữ làm họ bỡ ngỡ.

Sự ép buộc không phải là ma quỷ hay sự bất ngờ. Thực tế,phần lớn các trường hợp chính bạn có thể xây dựng với kiểu ép buộc hợp lý và dễ hiểu, thậm chí còn có thể sử dụng để cải
thiện khả năng đọc code.

Dưới đây là ví dụ của ép buộc minh bạch:

var a = "42";
var b = Number( a );
a; // "42"
b; // 42 -- số!

Và dưới đây là ví dụ của ép buộc không minh bạch:

var a = "42";
var b = a * 1; // "42" ép buộc ngầm 42 tại đây
a; // "42"
b; // 42 -- số!

Đúng và Sai

Trong chương 1, chúng ta đã đề cập ngắn gọn đến tính “truthy” và “falsy” tự nhiên của giá trị: khi một giá trị không phải boolean bị ép thành boolean, nó có trở thành tính true hay false tương ứng?
Danh sách cụ thể của giá trị “falsy” trong JS:

● “” (chuỗi rỗng)
● 0, -0, NaN (number không hợp lệ)
● null, undefined
● false

Bất kỳ giá trị nào không phải “falsy” thì là “truthy”. Đây là ví dụ:

  • “hello”
  • 42
  • true
  • [ ], [ 1, “2”, 3 ] (arrays)
  • { }, { a: 42 } (objects)
  • function foo() { .. } (functions)

Điều quan trọng là phải nhớ rằng giá trị boolean chỉ theo sự cưỡng ép “truthy”/”falsy” nếu nó bị ép theo boolean.

Đẳng thức

Có bốn loại đẳng thức: ==, ===, !=, và !==. Dạng ! tất nhiên là bản “không bình đẳng” đối xứng với các đối chiếu của nó; không nên nhầm lẫn giữa không bằng tuyệt đối và không bằng tương đối.
Sự khác biệt giữa == và === thường được đặc trưng hóa rằng == kiểm tra bằng nhau của giá trị và === kiểm tra bằng nhau cả giá trị lẫn kiểu. Tuy nhiên, điều này không đúng. Cách thích hợp để đặc trưng hóa chúng là ==kiểm tra bằng nhau của giá trị với
việc ép buộc được cho phép, và ===không cho phép cưỡng bức.

=== thường được gọi là “bình đẳng nghiêm ngặt” (strict equality) vì lý do này.
Xem sự ép buộc ngầm cho phép bằng cách so sánh bình đẳng == và không được phép với sự ép buộc nghiêm ngặt ===:

var a = "42";
var b = 42;
a == b; // true
a === b; // false

Trong việc so sánh a == b, JS nhận thấy rằng kiểu không trùng khớp, nên nó phải qua một loạt các bước theo trình tự ép buộc một hoặc cả hai giá trị khác kiểu cho đến khi chúng phù hợp,tại điểm này một phép so sánh giá trị đơn giản có thể được kiểm tra.
Nếu bạn nghĩ, có hai cách để a == b có thể true thông qua ép buộc. Hoặc nó được so sánh là 42 == 42 hoặc nó là “42” == “42”, thì nó là cái nào?

Câu trả lời: “42” trở thành 42, để so sánh 42 == 42. Trong ví dụ đơn giản, nó cũng không thực sự quan trọng tiến trình nào xảy ra, vì kết quả cũng như nhau. Nhưng đối với trường hợp phức tạp hơn thì nó quan trọng bởi vì nó không chỉ là kết quả của việc so sánh, mà là làm thế nào để dẫn tới điều này.
a === b tạo nên false bởi vì sự ép buộc không cho phép, vì vậy sự so sánh đơn giản của giá trị đương nhiên sai. Nhiều lập trình viên cảm thấy ===có thể dự đoán được, vậy nên họ hay dùng mẫu này và tránh xa ==.

Để làm rõ toàn bộ những chi tiết của vài điều cần ghi nhớ đơn giản, giúp bạn biết được khi nào thì dùng == hay ===, tôi liệt kê một số nguyên tắc sau:

● Nếu một trong hai bên trong phép so sánh là có thể là giá trị true hoặc false, tránh dùng == mà dùng ===.
● Nếu một trong hai bên trong phép so sánh là có thể một giá trị cụ thể (0, “”, hoặc [] — array rỗng), tránh ==mà dùng ===.
● Trong tất cả các trường hợp khác, bạn yên tâm dùng ==. Không chỉ vì nó an toàn, đơn giản là giúp code của bạn dễ đọc hơn trong nhiều trường hợp.

Những nguyên tắc trên là để yêu cầu bạn suy nghĩ nghiêm túc về code của bạn và về những loại giá trị nào có thể đi qua các biến để được so sánh bằng. Nếu bạn chắc chắn về giá trị, và == an toàn, hãy dùng nó! Nếu bạn không thể chắc chắn về giá trị,sử dụng ===. Đơn giản vậy thôi.
Ký hiệu không bằng != đi cặp với ==, và !== đi với ===. Tất cả các quy tắc và quan sát chúng ta vừa thảo luận đều cũng được áp dụng với phép so sánh không bằng này.
Bạn nên chú ý đặc biệt về các so sánh == và === khi so sánh hai giá trị không phải là nguyên thủy, như là object ( bao gồm function và array). Bởi vì các giá trị đó là tham chiếu, cả == và === đều kiểm tra khi nào các tham chiếu phù hợp chứ không phải các giá trị bên trong.
Ví dụ, array được mặc định ép buộc sang string bằng cách đơn giản gộp tất cả các giá trị với dấu phẩy (,) ở giữa. Bạn có thể nghĩ là hai array với nội dung như nhau có thể là ==, nhưng không phải:

var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
a == c; // true
b == c; // true
a == b; // false

 

BÌNH LUẬN

Nhập bình luận của bạn
Vui lòng nhập tên