post-image

Phân biệt toán tử == và === trong JavaScript

Biến, kiểu dữ liệu và toán tử

Trong JavaScript, các toán tử == và === được sử dụng để so sánh giữa hai toán hạng. Lúc viết code thì chỉ thấy mọi người dùng === chứ chẳng ai dùng ==, nhớ mang máng nó như thế này, như thế nọ mà không hiểu rõ bản chất của 2 toán tử này. Bài viết này sẽ giúp bạn phân biệt rõ == và ===, khi nào nên sử dụng chúng.


Sự khác biệt giữa == và ===

Đầu tiên, ta hãy nói về thuật ngữ mà JavaScript định nghĩa:

Hai bằng (==) được gọi là toán tử so sánh trừu tượng
Ba bằng (===) được gọi là toán tử so sánh cân bằng nghiêm ngặt.

Sự khác biệt giữa chúng có thể được tổng kết như sau:

Toán tử so sánh trừu tượng sẽ cố gắng giải quyết các kiểu dữ liệu thông qua việc chuyển đổi kiểu dữ liệu trước khi so sánh. Còn toán tử so sánh nghiêm ngặt sẽ trả về false nếu các giá trị khác nhau. Cụ thể, hãy xem ví dụ dưới đây:

console.log(3 == "3"); // true

console.log(3 === "3"); // false

Nhìn vào ví dụ trên, thì toán tử == trả về true vì chuỗi “3” được chuyển thành số 3 trước khi việc so sánh được thực hiện. Trong khi === cho thấy rằng đây là 2 kiểu dữ liệu khác nhau nên trả về false. Khá dễ hiểu phải không, một ví dụ khác nhé:

console.log(true == '1'); // true

console.log(true === '1'); // false

Ta thấy, 1 lần nữa, việc so sánh trừu tượng đã thực hiện chuyển đổi kiểu dữ liệu. Cụ thể là kiểu Boolean true và chuỗi “1” được chuyển đổi thành số 1 và kết quả so sánh là true. Còn như bình thường thì so sánh nghiêm ngặt sẽ trả về false. Nhìn vào 2 ví dụ đơn giản trên thì chúng ta đã phần nào phân biệt được sự khác nhau giữa == và ===. Tuy nhiên, trong thực tế có 1 vài trường hợp mà hành vi của các toán tử này không trực quan. Chúng ta hãy xem xét 1 số ví dụ khác:

console.log(undefined == null); // true
 
console.log(undefined === null); // false. Undefined and null
are distinct types and are not interchangeable.
console.log(true == 'true'); // false. A string will not be
converted to a boolean and vice versa.
 
console.log(true === 'true'); // false

Nếu các bạn chưa hiểu rõ undefined là gì, hãy đọc bài viết Phân biệt Null, Undefined và NaN.

Chú ý chút nha, ví dụ dưới dây khá thú vị vì nó mình họa 1 chuỗi bình thường với các đối tượng chuỗi (String Object):

console.log("This is a string." == new String("This is
a string.")); // true
 
console.log("This is a string." === new String("This is
a string.")); // false

Và để biết tại sao việc sử dụng === lại trả về false, chúng ta console lên thử xem thế nào nhé:

console.log(typeof "This is a string."); // string
 
console.log(typeof new String("This is a string.")); // object

Có thể thấy toán tử new sẽ luôn trả về 1 đối tượng và bạn sẽ nhận được kết quả tương tự khi so sánh các số nguyên thủy và các phép toán logic với các hàm tương ứng.

Với các toán hạng tham chiếu

Mở rộng hơn 1 chút, so sánh các toán hạng tham chiếu (so sánh bắc cầu). Nói về các đối tượng, điều gì sẽ xảy ra nếu chúng ta muốn so sánh các kiểu tham chiếu? So sánh trừu tượng và nghiêm ngặt sẽ thực hiện khác nhau như thế nào khi chúng ta dùng với các đối tượng?

Ở đây có 1 quy tắc các bạn cần lưu ý: khi so sánh kiểu bắc cầu thì cả so sánh trừu tượng và so sánh nghiêm ngặt sẽ trả về false, trừ khi cả 2 toán hạng đề cập đến cùng 1 đối tượng chính xác, để làm rõ hơn chúng ta xem ví dụ dưới đây:

var a = [];
var b = [];
var c = a;
 
console.log(a == b); // false
console.log(a === b); // false
console.log(a == c); // true
console.log(a === c); // true

Có thể thấy, mặc dù a và b là cùng loại và có giá trị như nhau nhưng kết quả trả về của cả 2 kiểu so sánh == và === đều là false.


Vậy khi nào nên sử dụng?

Lời khuyên từ các chuyên gia thì chúng ta nên sử dụng toán tử ba bằng vì theo như những giải thích ở trên, việc sử dụng so sánh nghiêm ngặt sẽ làm tăng sự rõ ràng của code của bạn (nhiều lúc không phải vắt óc suy nghĩ hay cố gắng ghi nhớ các quy tắc chuyển đổi kiểu dữ liệu lằng nhằng) và giúp ngăn chặn những sai sót phát sinh từ việc sử dụng so sánh trừu tượng. Nói có sách, mách có chứng, mình xin phép trích lời Nicholas Zakas tác giả cuốn sách JavaScript for Web Developers như sau “This helps to maintain data type integrity throughout your code” – dịch: “Điều này giúp duy trì tính toàn vẹn của kiểu dữ liệu trong suốt mã của bạn”

Tuy nhiên, nếu bạn thực sự nắm được vấn đề cốt lõi của 2 loại toán tử này thì việc sử dụng === hay === sẽ không còn là vấn đề cần lo lắng nữa. Giao bạn 1 task khó như thế nào đi chăng nữa thì kiểu gì bạn cũng làm được thôi!

Còn để tốt hơn nữa, khi bạn cần so sánh các giá trị của các loại khác nhau, hãy tự chuyển đổi đưa về cùng kiểu dữ liệu, rồi so sánh cho đoạn mã rõ ràng và không làm cho những người đọc code của bạn bị choáng.

Các bạn có thể tham khảo các bài viết hay về JavaScript tại đây.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

Trở thành lập trình viên từ con số 0
Tags:
,

Leave a Reply

Your email address will not be published. Required fields are marked *