boolean trong một câu lệnh if


144

Hôm nay tôi đã nhận được một nhận xét về mã xem xét cách tôi kiểm tra xem một biến là đúng hay sai trong bài tập của trường.

Mã mà tôi đã viết là một cái gì đó như thế này:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

Họ nói rằng tốt hơn / gọn gàng hơn để viết nó như thế này:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

Nhận xét mà tôi đã nhận được về phần "=== true" là nó không cần thiết và có thể tạo ra sự nhầm lẫn.

Tuy nhiên, ý tưởng của tôi là tốt hơn để kiểm tra xem biến đó có phải là boolean hay không, đặc biệt là vì Javascript là ngôn ngữ lỏng lẻo.

Trong ví dụ thứ hai, một chuỗi cũng sẽ trả về "một cái gì đó";

Vì vậy, câu hỏi của tôi; Là nó gọn gàng hơn để mất phần "=== true" trong tương lai, hay nó cũng là một thực hành tốt để kiểm tra loại biến.

Chỉnh sửa: Trong mã "thực" của tôi, boolean đại diện cho dù hình ảnh đã bị xóa hay chưa, do đó, các giá trị duy nhất boolValue nên có là đúng hay sai.

Ví dụ 0 và 1 không nên nằm trong biến đó.


4
có thể đọc và thực hành tốt để sử dụng ===
Piyas De

2
+1 cho === true. Tránh nhầm lẫn !!
gashu

1
@gashu Xem xét [0] === trueđánh giá thành sai.
Nghỉ ngơiRobot

1
@Jlange không nên? Vui lòng giải thích
gashu

Điều tôi muốn nói là, nếu bạn chỉ đơn giản muốn kiểm tra sự tồn tại "trung thực", thì tuyên bố đó sẽ thất bại, mặc dù nó sẽ đánh giá là đúng ([0] đánh giá là đúng nhưng không phải không có chuyển đổi loại). Nó thực sự phụ thuộc vào những gì bạn đang cố gắng thực hiện với tuyên bố của bạn. Sử dụng === truekhi bạn cần đảm bảo rằng điều kiện này chính xác bằng true.
Nghỉ ngơiRobot

Câu trả lời:


222

Trước hết, sự thật:

if (booleanValue)

Sẽ đáp ứng ifcâu lệnh cho bất kỳ giá trị trung thực nào booleanValuebao gồm true, mọi số khác không, mọi giá trị chuỗi không trống, bất kỳ tham chiếu đối tượng hoặc mảng, v.v ...

Mặt khác:

if (booleanValue === true)

Điều này sẽ chỉ đáp ứng ifđiều kiện nếu booleanValuechính xác bằng true. Không có giá trị trung thực khác sẽ đáp ứng nó.

Mặt khác, nếu bạn làm điều này:

if (someVar == true)

Sau đó, những gì Javascript sẽ làm là gõ cưỡng chế trueđể khớp với loại someVarvà sau đó so sánh hai biến. Có rất nhiều tình huống mà điều này có khả năng không phải là những gì người ta sẽ có ý định. Bởi vì điều này, trong hầu hết các trường hợp bạn muốn tránh ==vì có một bộ quy tắc khá dài về cách Javascript sẽ loại hai thứ cùng loại và trừ khi bạn hiểu tất cả các quy tắc đó và có thể dự đoán mọi thứ mà trình thông dịch JS có thể làm khi đưa ra hai loại khác nhau (mà hầu hết các nhà phát triển JS không thể), bạn có thể muốn tránh ==hoàn toàn.

Như một ví dụ về mức độ khó hiểu của nó:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

Đối với giá trị 2, bạn sẽ nghĩ rằng đó 2là một giá trị trung thực vì vậy nó sẽ được so sánh thuận lợi true, nhưng đó không phải là cách thức hoạt động của kiểu ép buộc. Nó đang chuyển đổi giá trị bên tay phải để khớp với loại giá trị bên trái để nó chuyển đổi truethành số 1để so sánh 2 == 1đó chắc chắn không phải là điều bạn dự định.

Vì vậy, người mua hãy cẩn thận. Có thể tốt nhất nên tránh ==trong gần như tất cả các trường hợp trừ khi bạn biết rõ ràng các loại bạn sẽ so sánh và biết tất cả các loại thuật toán cưỡng chế có thể hoạt động như thế nào.


Vì vậy, nó thực sự phụ thuộc vào các giá trị dự kiến booleanValuevà cách bạn muốn mã hoạt động. Nếu bạn biết trước rằng nó sẽ chỉ có một truehoặc một falsegiá trị, thì hãy so sánh nó với

if (booleanValue === true)

chỉ là mã bổ sung và không cần thiết và

if (booleanValue)

nhỏ gọn hơn và được cho là sạch hơn / tốt hơn.

Mặt khác, nếu bạn không biết điều gì booleanValuecó thể xảy ra và bạn muốn kiểm tra xem nó có thực sự được đặt thành truekhông có chuyển đổi loại tự động nào khác không, thì

if (booleanValue === true)

không chỉ là một ý tưởng tốt, nhưng được yêu cầu.


Ví dụ, nếu bạn xem việc triển khai .on()trong jQuery, nó có giá trị trả về tùy chọn. Nếu cuộc gọi lại trả về false, thì jQuery sẽ tự động dừng việc truyền bá sự kiện. Trong trường hợp cụ thể này, vì jQuery muốn tuyên truyền dừng CHỈ nếu falseđược trở lại, họ kiểm tra explicity giá trị trả về cho === falsevì họ không muốn undefinedhoặc 0hoặc ""hoặc bất cứ điều gì khác mà sẽ tự động gõ-convert false để đáp ứng cũng so sánh.

Ví dụ: đây là mã gọi lại xử lý sự kiện jQuery:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

Bạn có thể thấy rằng jQuery đang tìm kiếm rõ ràng ret === false.

Tuy nhiên, cũng có nhiều vị trí khác trong mã jQuery nơi kiểm tra đơn giản hơn phù hợp với mong muốn của mã. Ví dụ:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...

Tôi đã suy nghĩ về câu hỏi này trong một thời gian, nhưng không có cơ hội để tìm bất cứ ai để hỏi. Tôi sẽ đánh giá cao nếu bạn có thể xem. stackoverflow.com/questions/32615466/
Mạnh

Câu trả lời này không hoàn toàn chính xác. 'x == true' sẽ không đúng với các số khác không.
Teemoh

@Teemoh - Tôi không hiểu bình luận của bạn. Xem jsfiddle.net/jfriend00/89h8d8tm .
jfriend00

1
Tôi chỉ muốn nói rằng 'if (x)' không giống với 'if (x == true)', giống như bạn đã viết trong đoạn đầu tiên của câu trả lời của bạn. 'if (x)' sẽ chuyển đổi rõ ràng 'x' thành biểu diễn boolean của nó. 'if (x == true)' sẽ sử dụng Thuật toán so sánh trừu tượng EcmaScript. Bạn đã viết rằng 'if (x == true)' sẽ đúng với mọi số khác không hoặc chuỗi không trống hoặc bất kỳ đối tượng nào. Điều này chỉ sai. Nếu tôi chạy ví dụ của bạn với 2 thay vì 1 thì nó sẽ không hoạt động.
Teemoh

2
@Teemoh - Tôi thấy quan điểm của bạn. Trả lời sửa chữa và làm rõ và tôi đã thêm một phần về loại cưỡng chế với một ví dụ cho thấy làm thế nào nó có thể làm những điều bất ngờ.
jfriend00

40

Nếu bạn viết : if(x === true), nó sẽ chỉ đúng với x = true

Nếu bạn viết : if(x), nó sẽ đúng với mọi x không phải là: '' (chuỗi rỗng), false, null, không xác định, 0, NaN.


(chuỗi trống), false, null, không xác định, 0, NaN
Oliboy50

Đừng quên NaN-0.
haykam

8

Trong "nếu" đơn giản, biến sẽ được ép buộc thành Boolean và nó sử dụng toBoolean trên đối tượng: -

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, 0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

Nhưng so sánh với === không có bất kỳ sự ép buộc nào, vì vậy chúng phải bằng nhau mà không bị ép buộc.

Nếu bạn đang nói rằng đối tượng thậm chí có thể không phải là Boolean thì bạn có thể phải xem xét nhiều hơn là đúng / sai.

if(x===true){
...
} else if(x===false){
....
} else {
....
}

5

Nó phụ thuộc vào usecase của bạn. Việc kiểm tra loại cũng có thể có ý nghĩa, nhưng nếu đó chỉ là một lá cờ, thì không.


Việc ===so sánh không thực hiện kiểu ép buộc. Vì vậy, mã của OP thực sự kiểm tra loại cờ. Nó chỉ thành công nếu giá trị là boolean và là đúng.
Jesse Hallett

Hãy để tôi nói lại. Nếu bạn biết nó sẽ đúng hoặc sai, nó không thành vấn đề.
Ven

5

Nói chung, nó là sạch hơn và đơn giản hơn để bỏ qua === true.

Tuy nhiên, trong Javascript, những tuyên bố đó là khác nhau.

if (booleanValue)sẽ thực hiện nếu booleanValuetruthy - bất cứ điều gì khác hơn 0, false, '', NaN, null, và undefined.

if (booleanValue === true)sẽ chỉ thực hiện nếu booleanValuechính xác bằng true.


Đó chính xác là những gì tôi muốn chắc chắn, ngay cả khi tôi chỉ muốn boolValue là đúng hay sai. Biến được đặt thành true / false nhiều lần trong mã. Tôi biết rằng khi tôi viết mã, nhưng nếu tôi kiểm tra lại mã một năm sau đó thì đó chỉ là một dấu hỏi lớn trừ khi tôi đọc lại mọi thứ phải không?
DirkZz

@aldanux: Rất tiếc; Tôi có nghĩa ''.
SLaks

4

(===)Toán tử nhận dạng hành xử giống hệt với (==)toán tử đẳng thức ngoại trừ không có chuyển đổi loại nào được thực hiện và các loại phải giống nhau để được coi là bằng nhau.


Câu cuối cùng của bạn là sai. Hãy thử hai báo cáo của bạn if (booleanValue)if (booleanValue==true)khi booleanValue2. Hai tuyên bố đó không cho bạn kết quả như nhau.
jfriend00

Hấp dẫn. Ill dùng từ ngữ của bạn cho nó. Tôi đã suy nghĩ trong thế giới ObjC / C / C ++, trong JS Tôi cho rằng bạn đúng, vì các kiểu dữ liệu trong JS có thể được thay đổi và 2 == true sẽ không định lượng được nếu sau đó.
PHẦN MỀM Apollo

1
Xem câu trả lời của tôi ở trên cho ví dụ cụ thể này. Nó liên quan đến cách Javascript thực hiện chuyển đổi loại tự động để so sánh hai giá trị của các loại khác nhau.
jfriend00

3

Vì giá trị được kiểm tra Booleannên ưu tiên sử dụng trực tiếp cho ít mã hóa hơn và hoàn toàn làm như vậy==true


2

Vì bạn đã khởi tạo rõ ràng là bool, tôi nghĩ ===toán tử là không bắt buộc.


2

Nếu biến chỉ có thể nhận các giá trị boolean, thì sử dụng cú pháp ngắn hơn là hợp lý.

Nếu nó có khả năng có thể được gán các loại khác, và bạn cần phải phân biệt truetừ 1hay "foo", sau đó bạn phải sử dụng === true.


2

Tôi nghĩ rằng lý luận của bạn là âm thanh. Nhưng trong thực tế tôi đã thấy rằng việc bỏ qua sự ===so sánh là phổ biến hơn nhiều . Tôi nghĩ rằng có ba lý do cho điều đó:

  1. Nó thường không thêm vào ý nghĩa của biểu thức - đó là trong trường hợp giá trị được biết là boolean.
  2. Bởi vì có rất nhiều sự không chắc chắn về loại trong JavaScript, buộc việc kiểm tra loại có xu hướng cắn bạn khi bạn nhận được một giá trị bất ngờ undefinedhoặc nullgiá trị. Thường thì bạn chỉ muốn bài kiểm tra của mình thất bại trong những trường hợp như vậy. (Mặc dù tôi cố gắng cân bằng quan điểm này với phương châm "thất bại nhanh").
  3. Các lập trình viên JavaScript thích chơi nhanh và lỏng lẻo với các loại - đặc biệt là trong các biểu thức boolean - bởi vì chúng ta có thể.

Xem xét ví dụ này:

var someString = getInput();
var normalized = someString && trim(someString);  
// trim() removes leading and trailing whitespace

if (normalized) {
    submitInput(normalized);
}

Tôi nghĩ rằng loại mã này không phải là hiếm. Nó xử lý các trường hợp getInput()lợi nhuận undefined, nullhoặc một chuỗi rỗng. Do hai đánh giá boolean submitInput()chỉ được gọi nếu đầu vào đã cho là một chuỗi chứa các ký tự không phải khoảng trắng.

Trong JavaScript &&trả về đối số đầu tiên của nó nếu nó sai hoặc đối số thứ hai của nó nếu đối số thứ nhất là trung thực; vì vậy normalizedsẽ được undefinednếu someStringkhông được xác định và vv. Điều đó có nghĩa là không có đầu vào nào cho các biểu thức boolean ở trên thực sự là các giá trị boolean.

Tôi biết rằng rất nhiều lập trình viên đã quen với việc kiểm tra kiểu mạnh khi xem mã như thế này. Nhưng lưu ý khi áp dụng kiểu gõ mạnh có thể sẽ yêu cầu kiểm tra nullhoặc undefinedgiá trị rõ ràng , điều này sẽ làm lộn xộn mã. Trong JavaScript không cần thiết.


1

Điều này phụ thuộc. Nếu bạn lo ngại rằng biến của bạn có thể kết thúc như một cái gì đó giải quyết thành TRUE. Sau đó, kiểm tra cứng là phải. Nếu không thì tùy bạn. Tuy nhiên, tôi nghi ngờ rằng cú pháp whatever == TRUEsẽ gây nhầm lẫn cho bất cứ ai biết những gì họ đang làm.


1

Trong Javascript, ý tưởng về boolean khá mơ hồ. Xem xét điều này:

 var bool = 0 
 if(bool){..} //evaluates to false

 if(//uninitialized var) //evaluates to false

Vì vậy, khi bạn đang sử dụng câu lệnh if, (hoặc bất kỳ câu lệnh điều khiển nào khác), người ta không phải sử dụng var "boolean". Do đó, theo tôi, phần "=== true" trong tuyên bố của bạn là không cần thiết nếu bạn biết đó là một boolean, nhưng hoàn toàn cần thiết nếu giá trị của bạn là một var "chân thực" mơ hồ. Thông tin thêm về booleans trong javscript có thể được tìm thấy ở đây .



1

Cũng có thể được kiểm tra với đối tượng Boolean, nếu bạn cần kiểm tra một đối tượng error={Boolean(errors.email)}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.