บูลีนในคำสั่ง if


144

วันนี้ฉันได้รับข้อสังเกตเกี่ยวกับรหัสโดยคำนึงถึงวิธีการตรวจสอบว่าตัวแปรเป็นจริงหรือเท็จในการมอบหมายงานของโรงเรียน

รหัสที่ฉันเขียนมีลักษณะดังนี้:

var booleanValue = true;

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

พวกเขาบอกว่ามันดีกว่าหรือดีกว่าที่จะเขียนแบบนี้:

var booleanValue = true;

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

คำพูดที่ฉันได้รับเกี่ยวกับส่วน "=== จริง" คือมันไม่จำเป็นและสามารถสร้างความสับสน

อย่างไรก็ตามความคิดของฉันคือมันจะดีกว่าที่จะตรวจสอบว่าตัวแปรเป็นบูลีนหรือไม่โดยเฉพาะอย่างยิ่งตั้งแต่ Javascript เป็นภาษาที่หลวม

ในตัวอย่างที่สองสตริงจะส่งคืน "บางอย่าง" ด้วย

ดังนั้นคำถามของฉัน มันจะดีกว่าที่จะปล่อยส่วน "=== จริง" ในอนาคตหรือไม่ก็เป็นการดีที่จะตรวจสอบชนิดของตัวแปรเช่นกัน

แก้ไข: ในรหัส "ของจริง" ของฉันบูลีนแสดงให้เห็นว่าภาพถูกลบหรือไม่ดังนั้นค่า boolValue เท่านั้นที่ควรจะมีจริงหรือเท็จ

ตัวอย่างเช่น 0 และ 1 ไม่ควรอยู่ในตัวแปรนั้น


4
มันสามารถอ่านได้และเป็นแนวปฏิบัติที่ดีในการใช้ ===
Piyas De

2
+1 === trueสำหรับ หลีกเลี่ยงความสับสน !!
gashu

1
@gashu พิจารณา[0] === trueประเมินว่าเป็นเท็จ
RestingRobot

1
@Jange ไม่ควรใช่หรือไม่ โปรดอธิบาย
gashu

สิ่งที่ฉันหมายถึงคือถ้าคุณเพียงแค่ต้องการตรวจสอบการมีอยู่ของ "ความจริง" ข้อความนั้นจะล้มเหลวแม้ว่ามันควรจะประเมินเป็นจริง ([0] ประเมินเป็นจริง แต่ไม่ใช่โดยไม่มีการแปลงประเภท) มันขึ้นอยู่กับว่าคุณพยายามทำอะไรให้สำเร็จด้วยคำพูดของคุณ ใช้เมื่อคุณต้องให้แน่ใจว่าว่าเงื่อนไขเป็นเท่ากับ=== true true
RestingRobot

คำตอบ:


222

ก่อนอื่นข้อเท็จจริง:

if (booleanValue)

จะตอบสนองifคำสั่งสำหรับค่าความจริงใด ๆ ของการbooleanValueรวมถึงtrueจำนวนที่ไม่เป็นศูนย์ใด ๆ ค่าสตริงที่ไม่ว่างใด ๆ การอ้างอิงวัตถุหรืออาร์เรย์ ฯลฯ ...

ในทางกลับกัน:

if (booleanValue === true)

นี้จะตอบสนองifเงื่อนไขถ้าเป็นเท่ากับbooleanValue trueไม่มีค่าความจริงอื่น ๆ จะพึงพอใจ

ในทางกลับกันถ้าคุณทำสิ่งนี้:

if (someVar == true)

จากนั้นสิ่งที่ Javascript จะทำคือ type coerce trueเพื่อให้ตรงกับชนิดของsomeVarแล้วเปรียบเทียบตัวแปรสองตัว มีหลายสถานการณ์ที่สิ่งนี้ไม่น่าเป็นไปได้ ด้วยเหตุนี้ในกรณีส่วนใหญ่คุณต้องการหลีกเลี่ยง==เนื่องจากมีกฎที่ค่อนข้างยาวเกี่ยวกับวิธีที่ Javascript จะพิมพ์บีบบังคับให้สองสิ่งเป็นประเภทเดียวกันและเว้นแต่คุณจะเข้าใจกฎเหล่านั้นทั้งหมดและสามารถคาดการณ์ได้ทุกอย่างที่ล่าม JS อาจทำได้เมื่อ มีสองประเภทแตกต่างกัน (ซึ่งนักพัฒนา JS ส่วนใหญ่ไม่สามารถทำได้) คุณอาจต้องการหลีกเลี่ยง==โดยสิ้นเชิง

เป็นตัวอย่างของความสับสนว่า:

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 

สำหรับค่า2คุณจะคิดว่า2เป็นค่าความจริงดังนั้นมันจะเปรียบเทียบได้ดีtrueแต่นั่นไม่ใช่วิธีการบีบบังคับประเภท มันกำลังแปลงค่ามือขวาให้ตรงกับประเภทของค่ามือซ้ายดังนั้นมันจึงแปลงtrueเป็นตัวเลข1ดังนั้นมันจึงเป็นการเปรียบเทียบ2 == 1ซึ่งไม่ใช่สิ่งที่คุณต้องการ

ดังนั้นผู้ซื้อระวัง เป็นไปได้ว่าจะดีที่สุดที่จะหลีกเลี่ยง==ในเกือบทุกกรณียกเว้นว่าคุณทราบชนิดที่คุณจะเปรียบเทียบอย่างชัดเจนและรู้ว่าการบังคับประเภทอัลกอริทึมที่เป็นไปได้ทั้งหมดทำงานอย่างไร


ดังนั้นจึงขึ้นอยู่กับค่าที่คาดหวังbooleanValueและวิธีที่คุณต้องการให้โค้ดทำงาน หากคุณรู้ล่วงหน้าว่ามันจะมีค่าtrueหรือfalseค่าเพียงอย่างเดียวให้เปรียบเทียบด้วย

if (booleanValue === true)

เป็นรหัสพิเศษและไม่จำเป็นและ

if (booleanValue)

มีขนาดกะทัดรัดและทำความสะอาดได้ดีกว่า

หากในอีกทางหนึ่งคุณไม่ทราบว่าbooleanValueอาจเป็นอะไรและคุณต้องการทดสอบว่ามีการตั้งค่าอย่างแท้จริงtrueโดยไม่อนุญาตให้มีการแปลงประเภทอัตโนมัติอื่น ๆ หรือไม่

if (booleanValue === true)

ไม่ใช่แค่ความคิดที่ดี แต่จำเป็น


ตัวอย่างเช่นหากคุณดูการใช้งาน.on()ใน jQuery จะมีค่าส่งคืนทางเลือก หากการเรียกกลับส่งผลfalseให้ jQuery จะหยุดการเผยแพร่กิจกรรมโดยอัตโนมัติ ในกรณีนี้โดยเฉพาะตั้งแต่ jQuery ต้องการที่จะขยายพันธุ์หยุดเท่านั้นถ้าfalseถูกส่งกลับพวกเขาตรวจสอบอย่างชัดเจนค่าตอบแทนสำหรับการ=== falseเพราะพวกเขาไม่ได้ต้องการundefinedหรือ0หรือ""หรือสิ่งอื่นที่จะพิมพ์แปลงโดยอัตโนมัติเพื่อเท็จยังตอบสนองการเปรียบเทียบ

ตัวอย่างเช่นต่อไปนี้คือ jQuery event handling code callback:

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

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

คุณจะเห็นว่า jQuery ret === falseอย่างชัดเจนมองหา

แต่ยังมีสถานที่อื่น ๆ อีกมากมายในรหัส jQuery ที่การตรวจสอบที่ง่ายกว่านั้นเหมาะสมตามความต้องการของรหัส ตัวอย่างเช่น:

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

ฉันคิดถึงคำถามนี้มาระยะหนึ่งแล้ว แต่ไม่มีโอกาสได้พบใครถาม ฉันขอขอบคุณถ้าคุณสามารถดู stackoverflow.com/questions/32615466/…
mmm

คำตอบนี้ไม่ถูกต้องสมบูรณ์ 'x == จริง' จะไม่เป็นจริงสำหรับหมายเลขที่ไม่ใช่ศูนย์
Teemoh

@Teemoh - ฉันไม่เข้าใจความคิดเห็นของคุณ ดูjsfiddle.net/jfriend00/89h8d8tm
jfriend00

1
ฉันแค่อยากจะบอกว่า 'if (x)' ไม่เหมือนกับ 'if (x == จริง)' เหมือนกับที่คุณเขียนไว้ในย่อหน้าแรกของคำตอบของคุณ 'if (x)' จะแปลง 'x' เป็นตัวแทนบูลีนอย่างชัดเจน 'if (x == จริง)' จะใช้อัลกอริทึมการเปรียบเทียบแบบนามธรรมของ EcmaScript คุณเขียนว่า 'if (x == จริง)' จะเป็นจริงสำหรับหมายเลขที่ไม่ใช่ศูนย์หรือสตริงที่ไม่ว่างหรือวัตถุใด ๆ นี่เป็นเพียงความผิด ถ้าฉันใช้ตัวอย่างกับ 2 แทน 1 มันจะไม่ทำงาน
Teemoh

2
@Teemoh - ฉันเห็นจุดของคุณ คำตอบถูกแก้ไขและทำให้กระจ่างและฉันเพิ่มส่วนในประเภทการข่มขู่ด้วยตัวอย่างที่แสดงวิธีการทำสิ่งที่ไม่คาดคิด
jfriend00

40

ถ้าคุณเขียน: if(x === true)มันจะเป็นจริงสำหรับ x = จริงเท่านั้น

หากคุณเขียน: if(x)มันจะเป็นจริงสำหรับxใด ๆที่ไม่ใช่: '' (สตริงว่าง), เท็จ, null, ไม่ได้กำหนด, 0, NaN


(สตริงว่าง), false, null, ไม่ได้กำหนด, 0, NaN
Oliboy50

อย่าลืมและNaN -0
haykam

8

ในธรรมดา "ถ้า" ตัวแปรจะถูกบังคับให้เป็นบูลีนและจะใช้ toBoolean บนวัตถุ: -

    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.

แต่การเปรียบเทียบกับ === ไม่มีการบีบบังคับประเภทใด ๆ ดังนั้นพวกเขาจะต้องเท่าเทียมกันโดยไม่ต้องมีการบีบบังคับ

หากคุณกำลังบอกว่าวัตถุอาจไม่ได้เป็นบูลีนคุณอาจต้องพิจารณามากกว่าแค่ความจริง / เท็จ

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

5

มันขึ้นอยู่กับ usecase ของคุณ มันอาจสมเหตุสมผลในการตรวจสอบประเภทเช่นกัน แต่ถ้าเป็นเพียงค่าสถานะก็ไม่ได้


การ===เปรียบเทียบไม่ได้ดำเนินการบังคับประเภท ดังนั้นรหัสของ OP จึงทดสอบประเภทของการตั้งค่าสถานะได้อย่างมีประสิทธิภาพ จะประสบความสำเร็จก็ต่อเมื่อค่านั้นเป็นบูลีนและเป็นจริง
Jesse Hallett

ให้ฉันใช้ถ้อยคำใหม่ หากคุณรู้ว่ามันจะเป็นจริงหรือเท็จก็ไม่สำคัญ
Ven

5

=== trueโดยทั่วไปก็คือทำความสะอาดและง่ายในการละเว้น

อย่างไรก็ตามใน Javascript ข้อความเหล่านั้นแตกต่างกัน

if (booleanValue)จะดำเนินการถ้าbooleanValueเป็นtruthy - สิ่งอื่นที่ไม่ใช่0, false, '', NaN, และnullundefined

if (booleanValue === true)จะดำเนินการถ้าเป็นอย่างแม่นยำเท่ากับbooleanValuetrue


ซึ่งเป็นสิ่งที่ฉันต้องการแน่ใจอย่างแน่นอนแม้ในขณะที่ฉันต้องการให้ boolValue เป็นจริงหรือเท็จเท่านั้น ตัวแปรได้รับการตั้งค่าเป็นจริง / เท็จหลายครั้งในรหัส ฉันรู้ว่าเมื่อฉันเขียนรหัส แต่ถ้าฉันตรวจสอบรหัสอีกครั้งในปีต่อมาแล้วมันเป็นเพียงเครื่องหมายคำถามขนาดใหญ่เว้นแต่ฉันจะอ่านทุกอย่างอีกครั้งใช่มั้ย
DirkZz

@aldanux: โอ๊ะโอ ''ฉันหมายถึง
SLAK

4

ตัว(===)ดำเนินการเอกลักษณ์ดำเนินการเหมือนกับตัวดำเนินการเท่าเทียมกัน(==)ยกเว้นการแปลงชนิดไม่ได้ทำและประเภทจะต้องเหมือนกันที่จะต้องพิจารณาเท่ากัน


ประโยคสุดท้ายของคุณผิด ลองสองงบของคุณif (booleanValue)และif (booleanValue==true)เมื่อเป็นbooleanValue 2ข้อความทั้งสองนั้นไม่ให้ผลลัพธ์ที่เหมือนกัน
jfriend00

น่าสนใจ ฉันจะเอาคำของคุณไป ฉันกำลังคิดในโลก ObjC / C / C ++ ใน JS ฉันคิดว่าคุณถูกต้องเนื่องจากประเภทข้อมูลใน JS สามารถเปลี่ยนแปลงได้และ 2 == จริงจะไม่ได้ปริมาณถ้านั้น
Apollo SOFTWARE

1
ดูคำตอบของฉันด้านบนสำหรับตัวอย่างเฉพาะนี้ มันเกี่ยวกับวิธีที่ Javascript ทำการแปลงชนิดอัตโนมัติเพื่อเปรียบเทียบค่าสองประเภทที่แตกต่างกัน
jfriend00

3

เนื่องจากค่าที่ตรวจสอบเป็นBooleanที่ต้องการใช้โดยตรงสำหรับการเข้ารหัสน้อยและทั้งหมดก็ทำเหมือนกัน==true


2

เนื่องจากคุณกำหนดค่าเริ่มต้นอย่างชัดเจนว่าเป็นบูลฉันคิดว่า===ไม่จำเป็นต้องใช้โอเปอเรเตอร์


2

หากตัวแปรสามารถรับค่าบูลีนได้เพียงอย่างเดียวก็มีเหตุผลที่จะใช้ไวยากรณ์ที่สั้นกว่านี้

ถ้ามันสามารถอาจจะได้รับมอบหมายประเภทอื่น ๆ และคุณจำเป็นต้องแยกแยะความแตกต่างtrueจาก1หรือแล้วคุณจะต้องใช้"foo"=== true


2

ฉันคิดว่าเหตุผลของคุณเป็นเสียง แต่ในทางปฏิบัติฉันพบว่ามันเป็นเรื่องธรรมดามากที่จะละเว้นการ===เปรียบเทียบ ฉันคิดว่ามีสามเหตุผลที่:

  1. มันมักจะไม่เพิ่มความหมายของการแสดงออก - ในกรณีที่ค่าเป็นที่รู้จักกันว่าบูลีนอยู่แล้ว
  2. เพราะมีการจัดการที่ดีของประเภทความไม่แน่นอนใน JavaScript บังคับให้มีการตรวจสอบชนิดมีแนวโน้มที่จะกัดคุณเมื่อคุณได้รับไม่คาดคิดundefinedหรือnullค่า บ่อยครั้งที่คุณต้องการให้การทดสอบของคุณล้มเหลวในกรณีเช่นนี้ (แม้ว่าฉันจะพยายามปรับสมดุลมุมมองนี้ด้วยคำขวัญ "ไม่เร็ว")
  3. โปรแกรมเมอร์จาวาสคริปต์ชอบที่จะเล่นกับประเภทที่รวดเร็ว - โดยเฉพาะในนิพจน์บูลีน - เพราะเราทำได้

ลองพิจารณาตัวอย่างนี้:

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

if (normalized) {
    submitInput(normalized);
}

ฉันคิดว่ารหัสประเภทนี้ไม่ใช่เรื่องแปลก สามารถจัดการกับกรณีที่getInput()ผลตอบแทนundefined, nullหรือสตริงที่ว่างเปล่า เนื่องจากการประเมินผลบูลีนสองครั้งsubmitInput()จะถูกเรียกใช้เฉพาะหากอินพุตที่กำหนดเป็นสตริงที่มีอักขระที่ไม่ใช่ช่องว่าง

ใน JavaScript &&จะส่งคืนอาร์กิวเมนต์แรกหากมันเป็นเท็จหรืออาร์กิวเมนต์ที่สองหากอาร์กิวเมนต์แรกเป็นความจริง ดังนั้นnormalizedจะเป็นundefinedถ้าsomeStringไม่ได้กำหนดและอื่น ๆ นั่นหมายความว่าไม่มีอินพุตไปยังนิพจน์บูลีนด้านบนเป็นค่าบูลีนจริง ๆ

ฉันรู้ว่าโปรแกรมเมอร์จำนวนมากที่คุ้นเคยกับการตรวจสอบประเภทที่รัดกุมเมื่อเห็นรหัสเช่นนี้ แต่หมายเหตุการใช้การพิมพ์ที่รัดกุมน่าจะต้องมีการตรวจสอบnullหรือundefinedค่าที่ชัดเจนซึ่งจะทำให้รหัสยุ่ง ในจาวาสคริปต์ที่ไม่จำเป็น


1

ขึ้นอยู่กับว่า หากคุณกังวลว่าตัวแปรของคุณอาจกลายเป็นสิ่งที่แก้ไขได้เป็น TRUE การตรวจสอบอย่างหนักนั้นเป็นสิ่งที่ต้องทำ ไม่อย่างนั้นมันก็ขึ้นอยู่กับคุณ อย่างไรก็ตามฉันสงสัยว่าไวยากรณ์whatever == TRUEจะสร้างความสับสนให้กับทุกคนที่รู้ว่าพวกเขากำลังทำอะไรอยู่


1

ใน Javascript แนวคิดเรื่องบูลีนนั้นค่อนข้างคลุมเครือ พิจารณาสิ่งนี้:

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

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

ดังนั้นเมื่อคุณใช้คำสั่ง if (หรือคำสั่งควบคุมอื่น ๆ ) อย่างใดอย่างหนึ่งไม่จำเป็นต้องใช้ "boolean" ประเภท var ดังนั้นในความคิดของฉันส่วน "=== จริง" ของคำสั่งของคุณไม่จำเป็นถ้าคุณรู้ว่ามันเป็นบูลีน แต่จำเป็นอย่างยิ่งถ้าคุณค่าของคุณคือ var "ความจริง" ที่คลุมเครือ เพิ่มเติมเกี่ยวกับบูลีนในจาวาสคริปต์ไว้สามารถพบได้ที่นี่



1

นอกจากนี้ยังสามารถทดสอบกับวัตถุบูลีนหากคุณต้องการทดสอบวัตถุ error={Boolean(errors.email)}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.