φυβλαςのβλογ
บล็อกของ phyblas



javascript เบื้องต้น บทที่ ๗: ความเป็นจริงเท็จและตัวดำเนินการทางตรรกศาสตร์
เขียนเมื่อ 2019/07/31 23:11
แก้ไขล่าสุด 2024/01/22 15:38


ความเป็นจริงเท็จ

บทที่แล้วได้พูดถึงวิธีการตั้งเงื่อนไขไปแล้ว

เงื่อนไขสามารถมาได้จากหลายทางด้วยกัน มีวิธีสร้างอยู่หลายวิธี

ในบทนี้จะพูดถึงรายละเอียดว่าการจะตัดสินว่าเงื่อนไขนั้นจริงหรือเท็จนั้นทำอย่างไร ในกรณีต่างๆ

สิ่งที่บอกถึงความจริงเท็จก็คือค่าบูล (boolean) ซึ่งมีอยู่แค่ ๒ ตัว คือ true และ false

ความจริงมีเพียงหนึ่งเดียวเสมอ นั่นก็คือ true

真実はいつもひとつ

ส่วนความเท็จเองก็มีแค่หนึ่งเดียวเหมือนกันคือ false



ตัวดำเนินการเปรียบเทียบ

ในบทที่ ๔ ก็ได้มีการเขียนถึงตัวดำเนินการพื้นฐานพวกบวกลบคูณหารไปแล้ว

ในทางการเขียนโปรแกรมนั้น ตัว > และ < ก็ถือเป็นตัวดำเนินการเช่นกัน เรียกว่าเป็นตัวดำเนินการเปรียบเทียบ

เมื่อนำข้อมูล ๒ ตัวมาเข้าตัวดำเนินการเปรียบเทียบจะได้ค่า true หรือ false มา และค่านี้สามารถนำไปใช้ใน if เพื่อกำหนดเงื่อนไขได้

ตัวดำเนินการเปรียบเทียบมีอยู่หลายตัว ได้แก่

เครื่องหมาย ตัวอย่าง ความหมาย
==
7==7 // true
7=="7" // true
1==true // true
0==false // true
6==7 // false
เท่ากับ
!=
8!=9 // true
8!="9" // true 
8!=8 // false
ไม่เท่ากับ
<
6<7 // true
6<6 // false
น้อยกว่า
<=
6<=6 // true
7<=6 // false
น้อยกว่าหรือเท่ากับ
>
5>4 // true
4>4 // false
มากกว่า
>=
4>=4 // true
4>=5 // false
มากกว่าหรือเท่ากับ
===
7===7 // true
7==="7" // false
1===true // false
เท่ากับ
!==
7!=="7" // true
7!==7 // false
1!==true // true
ไม่เท่ากับ

ให้ระวังว่าเวลาเทียบว่าเท่ากันหรือไม่นั้นจะใช้เครื่องหมายเท่ากับ ๒ หรือ ๓ ตัว คือ == หรือ === แต่ถ้าเครื่องหมาย = แค่ตัวเดียวจะมีความหมายว่าใช้ป้อนค่าทางขวาให้กับตัวแปรทางซ้าย



ความแตกต่างระหว่าง == / != และ === / !==

ข้อแตกต่างระหว่าง == และ === ก็คือ เวลาที่มีการเปรียบเทียบระหว่างข้อมูล ๒​ ชนิดที่เป็นต่างชนิดกันนั้นปกติแล้วถ้าใช้ == จะมีการแปลงชนิดข้อมูลให้เป็นชนิดเดียวกันเพื่อเปรียบเทียบกัน ถ้าเปลี่ยนแล้วเทียบเท่าเป็นตัวเดียวกันก็จะได้ true

แต่ถ้าเป็น === เวลาเจอข้อมูลคนละชนิดกันจะเป็น false ทันที

ตัวอย่างเช่นพอตัวเลขมาเจอสายอักขระ สายอักขระจะถูกแปลงเป็นตัวเลขแล้วจึงเทียบ
alert(5 == "5"); // ได้ true
alert(5 == "05"); // ได้ true
alert(5 === "5"); // ได้ false
alert(5 === 5); // ได้ true
alert(5 === 5.0); // ได้ true
alert("5" === "5"); // ได้ true

พูดง่ายๆก็คือ === มีความเข้มงวดในการเปรียบเทียบมากกว่า == การที่ === จะเป็นจริงได้ต้องเท่ากันทั้งค่าและชนิดข้อมูล

กรณีตัวเลขเทียบกับ true หรือ false ด้วย == ก็เช่นเดียวกัน true จะกลายเป็น 1 และ false จะกลายเป็น 0

โครงสร้าง switch case ที่กล่าวถึงในบทที่แล้วนั้นใช้ === เป็นตัวเทียบ ดังนั้นชนิดข้อมูลก็ต้องตรงตามที่ใส่ด้วย

ส่วน != นั้นก็คือไม่เท่ากับ ในทางคณิตศาสตร์คือเครื่องหมาย ≠ นั่นเอง

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



การเทียบมากกว่าหรือน้อยกว่า

เครื่องหมายมากกว่า > และน้อยกว่า < นั้น ใช้สัญลักษณ์ตรงกับในทางคณิตศาสตร์ จึงเข้าใจได้ง่ายในทันที

ส่วนเครื่องหมายน้อยกว่าหรือเท่ากับนั้นถ้าเป็นในทางคณิตศาสตร์จะใช้สัญลักษณ์ ≤ แต่ในคอมไม่สะดวกที่จะพิมพ์ตัวนี้เพราะไม่มีในแป้นพิมพ์จึงใช้เป็น <=

ในขณะที่ >= คือมากกว่าหรือเท่ากับ ตรงกับ ≥ ในทางคณิตศาสตร์

ทั้ง >, >=, <, <= นั้นสามารถใช้เปรียบเทียบข้อมูลที่ต่างกันได้เช่นเดียวกับ == และ != โดยถ้าฝั่งใดฝั่งหนึ่งเป็นตัวเลข จะมีการแปลงอีกตัวหนึ่งเป็นตัวเลขตามแล้วจึงเปรียบเทียบ

แต่ถ้าเป็นสิ่งที่แปลงเป็นตัวเลขไม่ได้จะได้ค่า false เสมอ

ตัวอย่าง
alert(5 > "5"); // ได้ false
alert(5 >= "04"); // ได้ true
alert(true < "2"); // ได้true
alert(false >= "-2"); // ได้ true
alert("5" <= 5.0); // ได้ true
alert("a" > 5); // ได้ false
alert("a" < 5); // ได้ false
alert("a" <= 5); // ได้ false
alert("a" >= 5); // ได้ false


ปัญหาของเลขทศนิยม

เมื่อมีการใช้ตัวดำเนินการเปรียบเทียบกับเลขทศนิยมมีข้อที่ควรต้องระวังเป็นอย่างมาก นั่นคือที่จริงแล้วการคำนวณภายในคอมพิวเตอร์นั้นมีพื้นฐานจากเลขฐานสอง แต่ว่าในการคำนวณทั่วไปของมนุษย์เรานั้นจะใช้เลขฐานสิบเป็นหลัก

ตัวอย่างปัญหาที่ยกกันบ่อยก็คือเมื่อคำนวณ 0.1+0.2
alert(0.1 + 0.2); // ได้ 0.30000000000000004

ผลที่ได้จะไม่ใช่ 0.3 อย่างที่ควรจะเป็น แต่มีทศนิยมเล็กๆปรากฏขึ้นมา ซึ่งถ้านำค่าที่ได้นี้ไปเปรียบเทียบกับ 0.3 ก็จะพบว่าได้ไม่เท่ากัน
alert(0.1 + 0.2 == 0.3); // ได้ false
alert(0.1 + 0.2 > 0.3); // ได้ true

ที่เป็นแบบนี้เพราะความคลาดเคลื่อนเล็กน้อยที่เกิดขึ้นจากการแปลงเลขฐานสองเป็นฐานสิบ

ความคลาดเคลื่อนที่เกิดขั้นนั้นโดยปกติแล้วจะน้อยมากอย่างที่เห็น จึงมักไม่ส่งผลต่อการคำนวณโดยทั่วไป แต่จะมีผลเมื่อเอาเลขมาเปรียบเทียบกัน เพราะจะพบว่า 0.1+0.2 มีค่ามากกว่า 0.3 แบบนี้ จึงทำให้เกิดผลที่ไม่พึงประสงค์

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

แต่ปัญหานี้จะไม่เกิดกับเลขจำนวนเต็ม ดังนั้นไม่ต้องเป็นห่วงว่า 1+2 จะไม่เท่ากับ 3 ที่ควรระวังจึงเป็นเลขทศนิยมเท่านั้น



การเปรียบเทียบสายอักขระ

หากนำสายอักขระมาเทียบกันจะเป็นการเทียบเนื้อหาที่อยู่ในสายอักขระนั้น ถ้าหากเหมือนกันทุกประการก็จะได้ true เมื่อเทียบด้วย ==

แต่เมื่อเทียบด้วยเครื่องหมายมากกว่าหรือน้อยกว่าจะเป็นการเทียบตัวอักษรตามลำดับอักษร โดยไล่เทียบจากตัวแรกไป ถ้าเหมือนกันจึงเทียบตัวต่อไป คล้ายการเรียงคำในพจนานุกรม แต่ลำดับของตัวอักษรนั้นจะเทียบตามลำดับในยูนิโค้ด พิมพ์เล็กพิมพ์ใหญ่ถือเป็นคนละตัว โดยตัวพิมพ์ใหญ่ทั้งหมดอยู่ลำดับก่อนตัวพิมพ์เล็กทั้งหมด

ตัวอย่าง
alert("ม่วน" == "ม่วน"); // ได้ true
alert("ม่วน" < "ม้วน"); // ได้ true
alert("Qué" == "qué"); // ได้ false
alert("Zeni" > "game"); // ได้ false

ตัวเลขที่อยู่ในสายอักขระก็เทียบกันแบบสายอักขระ ไม่ได้ถูกแปลงเป็นตัวเลข จึงต้องระวังสับสน หากอยากเทียบแบบตัวเลขต้องแปลงเป็นตัวเลขก่อนเอง
alert("22" > "4"); // ได้ false
alert("02" == "2.0"); // ได้ false
alert(parseInt("02") == parseFloat("2.0")); // ได้ true



การเปรียบเทียบ null และ undefined

null เมื่อถูกนำมาเปรียบเทียบด้วยมากกว่าหรือเท่ากับจะเสมือนว่ามีค่าเป็น 0 แต่ถ้าหากใช้เครื่องหมายเท่ากับเทียบกับ 0 ก็กลับจะพบว่าเป็นเท็จ
alert(null == null); // ได้ true
alert(null == "null"); // ได้ false
alert(null == 0); // ได้ false
alert(null <= 0); // ได้ true
alert(null >= "0"); // ได้ true
alert(null > -1); // ได้ true
alert(null < 0.1); // ได้ true
alert(null >= "0.01"); // ได้ false

ส่วน undefined จะไม่เท่ากับอะไรเลยนอกจากตัวเอง และ null และถ้าเปรียบเทียบมากกว่าหรือน้อยกว่าจะได้ false ตลอด
alert(undefined >= 0); // ได้ false
alert(undefined < 0); // ได้ false
alert(undefined == null); // ได้ true
alert(undefined == undefined); // ได้ true
alert(undefined >= undefined); // ได้ false
alert(undefined <= null); // ได้ false



ตัวดำเนินการทางตรรกศาสตร์

ในการสร้างเงื่อนไขที่ซับซ้อนขึ้นนั้น มักจะต้องเอาเงื่อนไขสองอย่างขึ้นไปมาประกอบเข้าด้วยกัน

สิ่งที่เอาเงื่อนไขมาประกอบกันนั้นเรียกว่า "ตัวดำเนินการทางตรรกศาสตร์" (logical operator)

ในจาวาสคริปต์มีใช้อยู่ ๒ ตัวคือ

- แอมเพอร์แซนด์คู่ && (และ)
- ขีดตั้งคู่ || (หรือ)

เมื่อเชื่อมด้วย && (และ) จะเป็นจริงเมื่อทั้งตัวซ้ายและขวาเป็นจริงทั้งคู่ นอกนั้นเป็นเท็จหมด

แต่ถ้าเชื่อมด้วย || (หรือ) แค่ตัวใดตัวหนึ่งเป็นจริงก็จะเป็นจริงแล้ว และจะเป็นเท็จเมื่อทั้งซ้ายและขวาเป็นเท็จทั้งคู่

a b a && b a || b
true true true true
true false false true
false true false true
false false false false


ตัวอย่าง
var x = 10;
alert(x > 7 && x < 13); // ได้ true
if (x > 7 && x < 13) { // เข้าเงื่อนไข
  alert("x มากกว่า 7 น้อยกว่า 13");
}

ตัวอย่างในทางตรงกันข้าม
var x = 14;
alert(x <= 7 || x >= 13); // ได้ true
if (x <= 7 || x >= 13) { // เข้าเงื่อนไข
  alert("x ไม่เกิน 7 หรือเป็น 13 ขึ้นไป");
}



ค่าความจริงเท็จในตัวข้อมูลชนิดต่างๆ

ที่จริงแล้วเวลาใช้ if ค่าที่ใส่ใน if ไม่จำเป็นจะต้องเป็น true หรือ false เสมอไป แต่ถ้าใส่ค่าอื่นลงไปจะถูกเปลี่ยนให้เป็น true หรือ false โดยอัตโนมัติ ขึ้นอยู่กับว่าเป็นค่าอะไร

ค่าความจริงเท็จที่อยู่ในตัวของข้อมูลแต่ละชนิดอาจสรุปได้ดังนี้

ชนิดข้อมูล true false
boolean true false
number ยกเว้น 0 และ NaN 0, NaN
string สายอักขระที่ไม่ว่างเปล่า สายอักขระเปล่า
object ยกเว้น null null
function จริงเสมอ -
undefined - undefined

หากเติมเครื่องหมายตกใจ ! นำหน้าไปจะทำให้ความเป็นจริงเท็จเป็นไปในทางตรงกันข้ามกับความจริงเท็จในตัว ดังนั้นหากเติมเครื่องหมายกตใจ ๒​ ตัวซ้อน !! ก็จะกลายเป็นการแปลงตัวนั้นเป็นหาค่าความจริงเท็จในตัวนั้นเอง

หรือจะใช้ฟังก์ชัน Boolean ก็ได้เช่นกัน ฟังก์ชันนี้มีไว้เปลี่ยนข้อมูลชนิดใดๆเป็น true หรือ false

ตัวอย่าง
alert(!!{}); // ได้ true
alert(!!1); // ได้ true
alert(!!""); // ได้ false
alert(!!"0"); // ได้ true
alert(!!null); // ได้ false
alert(Boolean(0)); // ได้false
alert(Boolean()); // ได้false

ลองใช้เป็นเงื่อนไขดู
if (1) { // เข้าเงื่อนไข
  alert("1 เป็นจริง");
}




-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> javascript

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文