From 940ba54ddf078be662473f8cf9fed2c7b3edc544 Mon Sep 17 00:00:00 2001 From: Prasit Tongpradit Date: Wed, 27 Mar 2024 23:44:43 +0700 Subject: [PATCH 1/4] Fix bug in login functionality --- .../11-logical-operators/article.md | 260 ++---------------- 1 file changed, 18 insertions(+), 242 deletions(-) diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index 078c6df40..ca48f9b96 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -1,45 +1,45 @@ -## ตัวดำเนินการตรรกะ +# ตัวดำเนินการตรรกะ -JavaScript มีตัวดำเนินการตรรกะ 4 ตัว ได้แก่ `||` (OR), `&&` (AND), `!` (NOT), และ `??` (Nullish Coalescing) ที่นี่เราจะครอบคลุม 3 ตัวแรก ตัวดำเนินการ `??` อยู่ในบทความถัดไป +ใน JavaScript มีตัวดำเนินการตรรกะ 4 ตัว ได้แก่ `||` (OR), `&&` (AND), `!` (NOT) และ `??` (Nullish Coalescing) ในที่นี้จะอธิบายเฉพาะ 3 ตัวแรก ส่วนตัว `??` จะอยู่ในบทความถัดไป -แม้ว่าจะเรียกว่า "ตรรกะ" แต่ก็สามารถนำไปใช้กับค่าทุกประเภท ไม่ใช่แค่แบบบูลีน ผลลัพธ์ของพวกมันก็สามารถเป็นประเภทใดก็ได้ +แม้จะเรียกว่า "ตรรกะ" แต่ก็สามารถใช้กับค่าประเภทอื่นๆ นอกเหนือจาก boolean ได้ และผลลัพธ์ที่ออกมาก็เป็นประเภทอะไรก็ได้เช่นกัน มาดูรายละเอียดกัน ## || (OR) -ตัวดำเนินการ "OR" แสดงด้วยเครื่องหมายเส้นแนวตั้งสองอัน: +เครื่องหมาย "OR" จะแทนด้วยสัญลักษณ์เส้นตั้งคู่ `||` แบบนี้: ```js result = a || b; ``` -ในการเขียนโปรแกรมแบบดั้งเดิม OR ตรรกะใช้สำหรับจัดการค่าบูลีนเท่านั้น ถ้าอาร์กิวเมนต์ใดๆ เป็น `true` มันจะส่งคืน `true` มิฉะนั้นจะส่งคืน `false` +โดยทั่วไปแล้ว OR ตรรกะมีไว้ใช้กับค่า boolean เท่านั้น ถ้ามี argument ตัวใดเป็น `true` ก็จะคืนค่า `true` ถ้าไม่มีเลยจะคืนค่า `false` -ใน JavaScript ตัวดำเนินการมีความซับซ้อนและมีประสิทธิภาพมากกว่าเล็กน้อย แต่ก่อนอื่น มาดูสิ่งที่เกิดขึ้นกับค่าบูลีนกัน +แต่ใน JavaScript นั้นตัวดำเนินการ OR มีความซับซ้อนและมีพลังมากกว่านั้นหน่อย แต่ก่อนอื่นมาดูว่าเกิดอะไรขึ้นกับค่า boolean ก่อน -มีสี่ชุดค่าตรรกะที่เป็นไปได้: +จะมีเคสที่เป็นไปได้ 4 แบบ: ```js run alert( true || true ); // true alert( false || true ); // true alert( true || false ); // true -alert( false || false ); // false +alert( false || false ); // false ``` -อย่างที่เราเห็น ผลลัพธ์คือ `true` เสมอ ยกเว้นกรณีที่ทั้งสองตัวถูกดำเนินการเป็น `false` +จะเห็นว่าผลลัพธ์จะเป็น `true` เสมอ ยกเว้นกรณีที่ operand ทั้งสองข้างเป็น `false` -ถ้าตัวดำเนินการไม่ใช่แบบบูลีน มันจะถูกแปลงเป็นแบบบูลีนเพื่อการประเมิน +ถ้า operand ไม่ใช่ boolean จะถูกแปลงเป็น boolean ก่อนแล้วค่อยประเมิน -ตัวอย่างเช่น ตัวเลข `1` ถูกตีความเป็น `true` ตัวเลข `0` เป็น `false`: +เช่น ตัวเลข `1` จะถือเป็น `true` ส่วนตัวเลข `0` จะเป็น `false`: ```js run -if (1 || 0) { // ทำงานเหมือนกับ if( true || false ) - alert( 'truthy!' ); +if (1 || 0) { // จะทำงานเหมือน if (true || false) + alert('truthy!'); } ``` -ส่วนใหญ่ OR `||` ใช้ในคำสั่ง `if` เพื่อทดสอบว่าเงื่อนไขใด *ก็ตาม* ในเงื่อนไขที่กำหนดเป็น `true` +ส่วนใหญ่แล้ว OR `||` จะใช้ในคำสั่ง `if` เพื่อตรวจว่ามีเงื่อนไขใดเป็น `true` บ้าง ตัวอย่างเช่น: @@ -49,241 +49,17 @@ let hour = 9; *!* if (hour < 10 || hour > 18) { */!* - alert( 'The office is closed.' ); + alert('ออฟฟิศปิดแล้ว'); } ``` -เราสามารถใส่เงื่อนไขเพิ่มเติมได้: +เราสามารถเพิ่มเงื่อนไขได้อีก: ```js run let hour = 12; let isWeekend = true; if (hour < 10 || hour > 18 || isWeekend) { - alert( 'The office is closed.' ); // วันหยุดสุดสัปดาห์ + alert('ออฟฟิศปิดแล้ว'); // เพราะเป็นวันหยุดสุดสัปดาห์ } -``` - -## || "OR" หาค่า truthy ตัวแรก [#or-finds-the-first-truthy-value] - -ตรรกะที่อธิบายไว้ข้างต้นค่อนข้างคลาสสิก ตอนนี้เรามาดู "ฟีเจอร์พิเศษ" ของ JavaScript กัน - -อัลกอริทึมที่ขยายแล้วทำงานดังนี้ - -กำหนดค่า OR หลายค่า: - -```js -result = value1 || value2 || value3; -``` - -ตัวดำเนินการ OR `||` ทำสิ่งต่อไปนี้: - -- ประเมินตัวดำเนินการจากซ้ายไปขวา -- สำหรับตัวดำเนินการแต่ละตัวแปลงเป็นแบบบูลีน ถ้าผลลัพธ์เป็น `true` ให้หยุดและส่งคืนค่าเดิมของตัวดำเนินการนั้น -- ถ้าประเมินตัวดำเนินการทั้งหมดแล้ว (ทั้งหมดเป็น `false`) จะส่งคืนตัวดำเนินการสุดท้าย - -ค่าจะถูกส่งคืนในรูปแบบเดิมโดยไม่เปลี่ยนแปลง - -กล่าวอีกนัยหนึ่ง OR `||` ช่วงหนึ่งจะส่งคืนค่า truthy ตัวแรก หรือตัวสุดท้ายถ้าไม่พบค่า truthy - -ตัวอย่างเช่น: - -```js run -alert( 1 || 0 ); // 1 (1 เป็น truthy) - -alert( null || 1 ); // 1 (1 เป็นค่า truthy ตัวแรก) -alert( null || 0 || 1 ); // 1 (ค่า truthy ตัวแรก) - -alert( undefined || null || 0 ); // 0 (ทั้งหมดเป็น falsy ส่งคืนค่าสุดท้าย) -``` - -สิ่งนี้นำไปสู่การใช้งานที่น่าสนใจเมื่อเทียบกับ "OR แบบคลาสสิก แบบบูลีนเท่านั้น" - -1. แสดงค่า truthy ตัวแรกจากรายการตัวแปรหรือนิพจน์ - -ยกตัวอย่างเช่น เราต้องการเลือกแสดงชื่อของผู้ใช้โดยใช้ตัวแปร `firstName`, `lastName`, `nickName` ซึ่งตัวแปรเหล่านี้อาจจะไม่มีข้อมูล (undefined) หรือมีค่าที่ไม่ใช่จริง (falsy) - -เราสามารถใช้ตัวดำเนินการ OR `||` เพื่อเลือกค่าแรกที่มีข้อมูลและแสดงผล (หรือแสดง `"คนไร้นาม"` ถ้าไม่มีข้อมูลเลย) - -```js run -let firstName = ""; -let lastName = ""; -let nickName = "SuperCoder"; - -*!* -alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder -*/!* -``` - -ถ้าตัวแปรทั้งหมดเป็น falsy โปรแกรมจะแสดง `"Anonymous"` - -2. การประเมินแบบลัดวงจร (Short-circuit evaluation) - -อีกหนึ่งฟีเจอร์ของตัวดำเนินการ OR `||` คือการประเมินแบบลัดวงจร (short-circuit) - -หมายความว่า `||` จะประมวลผลอาร์กิวเมนต์ของตัวเองจนกว่าจะเจอค่า truthy ตัวแรก จากนั้นจะส่งคืนค่านั้นทันที โดยไม่แตะอาร์กิวเมนต์อื่นเลย - -ความสำคัญของฟีเจอร์นี้จะชัดเจนขึ้นหากตัวถูกดำเนินการไม่ใช่แค่ค่า แต่เป็นนิพจน์ที่มีผลข้างเคียง เช่น การกำหนดตัวแปรหรือการเรียกใช้ฟังก์ชัน - -ในตัวอย่างด้านล่าง มีเพียงข้อความที่สองเท่านั้นที่ถูกพิมพ์: - - ```js run no-beautify - *!*true*/!* || alert("ไม่ถูกพิมพ์"); - *!*false*/!* || alert("ถูกพิมพ์"); - ``` - -ในบรรทัดแรก ตัวดำเนินการ OR `||` จะหยุดการประเมินทันทีที่เห็น `true` ดังนั้น `alert` จึงไม่ทำงาน - -บางครั้ง ผู้ใช้ฟีเจอร์นี้เพื่อสั่งให้รันคำสั่งเฉพาะในกรณีที่เงื่อนไขในส่วนซ้ายเป็น falsy - -## && (AND) - -ตัวดำเนินการ AND แสดงด้วยเครื่องหมาย ampersand สองตัว `&&`: - -```js -result = a && b; -``` - -ในการเขียนโปรแกรมแบบดั้งเดิม AND จะส่งคืน `true` ถ้าทั้งสองตัวถูกดำเนินการเป็น truthy มิฉะนั้นจะส่งคืน `false` : - -```js run -alert( true && true ); // true -alert( false && true ); // false -alert( true && false ); // false -alert( false && false ); // false -``` - -ตัวอย่างกับ `if`: - -```js run -let hour = 12; -let minute = 30; - -if (hour == 12 && minute == 30) { - alert( 'เวลานี้คือ 12:30' ); -} -``` - -เช่นเดียวกับ OR ค่าใดๆ ก็สามารถใช้เป็นตัวถูกดำเนินการของ AND: - -```js run -if (1 && 0) { // ประเมินเป็น true && false - alert( "ไม่ทำงาน เพราะผลลัพธ์เป็น falsy" ); -} -``` - - -## AND "&&" หาค่า falsy ตัวแรก - -กำหนดค่า AND หลายค่า: - -```js -result = value1 && value2 && value3; -``` - -ตัวดำเนินการ AND `&&` ทำสิ่งต่อไปนี้: - -- ประเมินตัวดำเนินการจากซ้ายไปขวา -- สำหรับตัวดำเนินการแต่ละตัวแปลงเป็นแบบบูลีน ถ้าผลลัพธ์เป็น `false` ให้หยุดและส่งคืนค่าเดิมของตัวดำเนินการนั้น -- ถ้าประเมินตัวดำเนินการทั้งหมดแล้ว (ทั้งหมดเป็น truthy) จะส่งคืนตัวดำเนินการสุดท้าย - -กล่าวอีกนัยหนึ่ง AND จะส่งคืนค่า falsy ตัวแรก หรือตัวสุดท้ายถ้าไม่พบค่า falsy - -กฎข้างต้นคล้ายกับ OR ความแตกต่างคือ AND ส่งคืนค่า *falsy* ตัวแรก ในขณะที่ OR ส่งคืนค่า *truthy* ตัวแรก - -ตัวอย่าง: - -```js run -// ถ้าตัวดำเนินการตัวแรกเป็น truthy -// AND จะส่งคืนตัวดำเนินการที่สอง: -alert( 1 && 0 ); // 0 -alert( 1 && 5 ); // 5 - -// ถ้าตัวดำเนินการตัวแรกเป็น falsy -// AND จะส่งคืนตัวนั้น ตัวดำเนินการตัวที่สองจะถูกละเว้น -alert( null && 5 ); // null -alert( 0 && "no matter what" ); // 0 -``` - -เราสามารถส่งค่าหลายค่าติดต่อกันได้ ดูว่าค่า falsy ตัวแรกถูกส่งคืนอย่างไร: - -```js run -alert( 1 && 2 && null && 3 ); // null -``` - -เมื่อค่าทั้งหมดเป็น truthy ค่าสุดท้ายจะถูกส่งคืน: - -```js run -alert( 1 && 2 && 3 ); // 3, the last one -``` - -````smart header="ลำดับความสำคัญของ AND `&&` สูงกว่า OR `||`" -ลำดับความสำคัญของตัวดำเนินการ AND `&&` สูงกว่า OR `||`. - -ดังนั้นโค้ด `a && b || c && d` จริงๆแล้วเหมือนกับว่านิพจน์ `&&` อยู่ในวงเล็บ: `(a && b) || (c && d)`. -```` - -````warn header="อย่าแทนที่ `if` ด้วย `||` หรือ `&&`" -บางครั้ง ผู้ใช้ตัวดำเนินการ AND `&&` เป็น "วิธีที่สั้นกว่าในการเขียน `if`". - -ตัวอย่างเช่น: - -```js run -let x = 1; - -(x > 0) && alert( 'Greater than zero!' ); - - -การกระทำทางด้านขวาของ `&&` จะดำเนินการเฉพาะในกรณีที่การประเมินไปถึงเท่านั้น นั่นคือ ในกรณีที่ `(x > 0)` เป็นจริง - -ดังนั้น โดยทั่วไป `&&` สามารถใช้แทน `if` ได้ แต่ไม่ใช่เสมอไป ดังนี้: - -js run -let x = 1; - -if (x > 0) alert( 'Greater than zero!' ); - - -แม้ว่าตัวแปร `&&` จะสั้นกว่า `if` แต่ `if` ก็ชัดเจนกว่าและอ่านง่ายกว่าเล็กน้อย ดังนั้นเราขอแนะนำให้ใช้แต่ละโครงสร้างตามวัตถุประสงค์: ใช้ `if` ถ้าเราต้องการ `if` และใช้ `&&` ถ้าเราต้องการ AND -```` - - -## ! (NOT) - -ตัวดำเนินการ NOT แบบบูลีนแสดงด้วยเครื่องหมายอัศเจรีย์ `!` - -ไวยากรณ์ค่อนข้างง่าย: - -```js -result = !value; -``` - -ตัวดำเนินการรับอาร์กิวเมนต์ตัวเดียวและทำสิ่งต่อไปนี้: - -1. แปลงตัวถูกดำเนินการเป็นประเภทบูลีน: `true/false` -2. ส่งคืนค่าผกผัน - -ตัวอย่างเช่น: - -```js run -alert( !true ); // false -alert( !0 ); // true -``` - -บางครั้งใช้ NOT `!!` ซ้อนกันเพื่อแปลงค่าเป็นประเภทบูลีน: - -```js run -alert( !!"non-empty string" ); // true -alert( !!null ); // false -``` - -นั่นคือ NOT ตัวแรกแปลงค่าเป็นบูลีนและส่งคืนค่าผกผัน และ NOT ตัวที่สองทำให้ผกผันอีกครั้ง สุดท้าย เรามีการแปลงค่าเป็นบูลีนอย่างง่าย - -มีวิธีที่ยาวกว่าเล็กน้อยในการทำสิ่งเดียวกัน -- ฟังก์ชัน `Boolean` ที่มีมาให้: - -```js run -alert( Boolean("non-empty string") ); // true -alert( Boolean(null) ); // false -``` - -ลำดับความสำคัญของ NOT `!` สูงที่สุดในบรรดาตัวดำเนินการตรรกะทั้งหมด ดังนั้นมันจะทำงานก่อนเสมอ ก่อน `&&` หรือ `||` +``` \ No newline at end of file From 74c1933186fb2bbde7007538207551066fc4ed36 Mon Sep 17 00:00:00 2001 From: Prasit Tongpradit Date: Wed, 27 Mar 2024 23:48:32 +0700 Subject: [PATCH 2/4] Add explanation of OR operator behavior in JavaScript --- .../11-logical-operators/article.md | 74 ++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index ca48f9b96..e5b960a58 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -62,4 +62,76 @@ let isWeekend = true; if (hour < 10 || hour > 18 || isWeekend) { alert('ออฟฟิศปิดแล้ว'); // เพราะเป็นวันหยุดสุดสัปดาห์ } -``` \ No newline at end of file +``` + +## OR "||" จะหาค่า truthy ตัวแรก + +ตรรกะที่อธิบายไว้ข้างต้นค่อนข้างเป็นแบบดั้งเดิม ทีนี้มาดูความสามารถ "พิเศษ" ของ JavaScript กัน + +อัลกอริทึมที่ขยายออกไปจะทำงานดังนี้ + +เมื่อมีหลายค่ามา OR กัน: + +```js +result = value1 || value2 || value3; +``` + +ตัวดำเนินการ OR `||` จะทำดังนี้: + +- ประเมิน operand จากซ้ายไปขวา +- สำหรับแต่ละ operand จะแปลงเป็น boolean ถ้าผลลัพธ์เป็น `true` จะหยุดและคืนค่าเดิมของ operand นั้นทันที +- ถ้าประเมิน operand ทั้งหมดแล้ว (คือทุกตัวเป็น `false`) จะคืนค่า operand ตัวสุดท้าย + +จะคืนค่าในรูปแบบเดิม โดยไม่มีการแปลงใดๆ + +อีกนัยหนึ่ง การเชื่อม OR `||` หลายตัวจะคืนค่า truthy ตัวแรกเสมอ หรือถ้าไม่เจอค่า truthy เลยจะคืนตัวสุดท้าย + +ตัวอย่างเช่น: + +```js run +alert( 1 || 0 ); // 1 (1 เป็น truthy) + +alert( null || 1 ); // 1 (1 เป็นค่า truthy ตัวแรก) +alert( null || 0 || 1 ); // 1 (ค่า truthy ตัวแรก) + +alert( undefined || null || 0 ); // 0 (ทั้งหมดเป็น falsy จึงคืนค่าตัวสุดท้าย) +``` + +พฤติกรรมนี้ทำให้มีวิธีใช้ OR ที่น่าสนใจเมื่อเทียบกับการใช้ OR แบบบูลีนอย่างเดียวทั่วไป + +1. **การหาค่า truthy ตัวแรกจาก list ของตัวแปรหรือนิพจน์ต่างๆ** + + เช่น สมมติเรามีตัวแปร `firstName`, `lastName` และ `nickName` ซึ่งล้วนแต่เป็นออปชันที่อาจจะเป็น undefined หรือมีค่า falsy ได้ + + เราสามารถใช้ OR `||` เพื่อเลือกเอาค่าที่เซ็ตข้อมูลแล้วมาแสดง (หรือถ้าไม่มีจะแสดง `"Anonymous"`): + + ```js run + let firstName = ""; + let lastName = ""; + let nickName = "SuperCoder"; + + *!* + alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder + */!* + ``` + + ถ้าทุกตัวแปรเป็น falsy ก็จะแสดง `"Anonymous"` + +2. **การประเมินแบบตัดตอนสั้น (short-circuit)** + + อีกความสามารถของตัวดำเนินการ OR `||` คือเรียกว่า "short-circuit evaluation" + + มันหมายความว่า `||` จะประมวลผลอาร์กิวเมนต์จนกว่าจะเจอค่า truthy ตัวแรก แล้วจะคืนค่านั้นทันทีเลย โดยไม่แตะอาร์กิวเมนต์ตัวถัดไปเลย + + ความสำคัญของความสามารถนี้จะเห็นได้ชัดเจน ถ้า operand ไม่ใช่แค่ค่าธรรมดา แต่เป็นนิพจน์ที่มี side-effect อย่างเช่นการกำหนดค่าตัวแปรหรือเรียกใช้ฟังก์ชัน + + ในตัวอย่างด้านล่าง จะพิมพ์แค่ข้อความที่สองเท่านั้น: + + ```js run no-beautify + *!*true*/!* || alert("จะไม่พิมพ์"); + *!*false*/!* || alert("จะพิมพ์"); + ``` + + ในบรรทัดแรก ตัว OR `||` จะหยุดประเมินทันทีที่เจอ `true` ดังนั้น `alert` จึงไม่ถูกเรียก + + บางครั้งก็มีคนใช้ความสามารถนี้เพื่อรันคำสั่งก็ต่อเมื่อเงื่อนไขทางซ้ายมือเป็น falsy ด้วย \ No newline at end of file From 448f617cf58833cb9386e008d64ed9c0d8f05526 Mon Sep 17 00:00:00 2001 From: Prasit Tongpradit Date: Wed, 27 Mar 2024 23:54:21 +0700 Subject: [PATCH 3/4] Add logical operators section --- .../11-logical-operators/article.md | 112 +++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index e5b960a58..fe29cfb0f 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -134,4 +134,114 @@ alert( undefined || null || 0 ); // 0 (ทั้งหมดเป็น falsy ในบรรทัดแรก ตัว OR `||` จะหยุดประเมินทันทีที่เจอ `true` ดังนั้น `alert` จึงไม่ถูกเรียก - บางครั้งก็มีคนใช้ความสามารถนี้เพื่อรันคำสั่งก็ต่อเมื่อเงื่อนไขทางซ้ายมือเป็น falsy ด้วย \ No newline at end of file + บางครั้งก็มีคนใช้ความสามารถนี้เพื่อรันคำสั่งก็ต่อเมื่อเงื่อนไขทางซ้ายมือเป็น falsy ด้วย + +## && (AND) + +เครื่องหมาย AND ใช้สัญลักษณ์ & สองตัวติดกัน `&&` แบบนี้: + +```js +result = a && b; +``` + +โดยปกติในการเขียนโปรแกรม AND จะคืนค่า `true` ถ้า operand ทั้งสองเป็น truthy และคืน `false` ในกรณีอื่นๆ: + +```js run +alert( true && true ); // true +alert( false && true ); // false +alert( true && false ); // false +alert( false && false ); // false +``` + +ตัวอย่างการใช้กับ `if`: + +```js run +let hour = 12; +let minute = 30; + +if (hour == 12 && minute == 30) { + alert( 'ขณะนี้เวลา 12:30 น.' ); +} +``` + +เหมือนกับ OR นั่นคือ operand ของ AND จะเป็นค่าอะไรก็ได้: + +```js run +if (1 && 0) { // ประเมินเป็น true && false + alert( "จะไม่ทำงาน เพราะผลลัพธ์เป็น falsy" ); +} +``` + +## AND "&&" จะหาค่า falsy ตัวแรก + +ถ้ามีหลายค่ามา AND กัน: + +```js +result = value1 && value2 && value3; +``` + +ตัวดำเนินการ AND `&&` จะทำงานดังนี้: + +- ประเมิน operand จากซ้ายไปขวา +- สำหรับแต่ละ operand จะแปลงเป็น boolean ถ้าผลลัพธ์เป็น `false` จะหยุดและคืนค่าเดิมของ operand นั้นทันที +- ถ้าประเมิน operand ทั้งหมดแล้ว (คือทุกตัวเป็น truthy) จะคืนค่า operand ตัวสุดท้าย + +อีกนัยหนึ่ง AND จะคืนค่า falsy ตัวแรกที่เจอ หรือถ้าไม่เจอเลยจะคืนค่าตัวสุดท้าย + +กฎข้างต้นคล้ายกับ OR ต่างกันตรงที่ AND คืนค่า *falsy* ตัวแรก ส่วน OR คืนค่า *truthy* ตัวแรก + +ตัวอย่าง: + +```js run +// ถ้า operand ตัวแรกเป็น truthy +// AND จะคืนค่า operand ตัวที่สอง: +alert( 1 && 0 ); // 0 +alert( 1 && 5 ); // 5 + +// ถ้า operand ตัวแรกเป็น falsy +// AND จะคืนค่านั้นเลย โดยไม่สนใจ operand ตัวที่สอง +alert( null && 5 ); // null +alert( 0 && "ไม่สำคัญ" ); // 0 +``` + +เราสามารถส่งหลายค่าต่อกันได้ ลองดูว่าค่า falsy ตัวแรกจะถูกคืนออกมา: + +```js run +alert( 1 && 2 && null && 3 ); // null +``` + +ถ้าค่าทั้งหมดเป็น truthy ค่าตัวสุดท้ายจะถูกคืน: + +```js run +alert( 1 && 2 && 3 ); // 3, ตัวสุดท้าย +``` + +````smart header="AND `&&` มีลำดับความสำคัญสูงกว่า OR `||`" +ตัวดำเนินการ AND `&&` จะมี precedence สูงกว่า OR `||` + +ดังนั้นโค้ด `a && b || c && d` ก็เหมือนกับการเขียนนิพจน์ `&&` อยู่ในวงเล็บ: `(a && b) || (c && d)` +```` + +````warn header="อย่าใช้ `||` หรือ `&&` แทนคำสั่ง `if`" +บางครั้งมีคนใช้ตัวดำเนินการ AND `&&` เพื่อ "เขียน `if` ให้สั้นลง" + +เช่น: + +```js run +let x = 1; + +(x > 0) && alert( 'มากกว่าศูนย์!' ); +``` + +การกระทำทางขวาของ `&&` จะรันก็ต่อเมื่อการประเมินทำไปถึงจุดนั้น ซึ่งก็คือเมื่อ `(x > 0)` เป็นจริง + +ดังนั้นมันจะเหมือนกับการเขียนแบบนี้: + +```js run +let x = 1; + +if (x > 0) alert( 'มากกว่าศูนย์!' ); +``` + +ถึงแม้การใช้ `&&` จะดูสั้นกว่า แต่ `if` จะชัดเจนและอ่านเข้าใจง่ายกว่า แนะนำให้ใช้แต่ละแบบตามวัตถุประสงค์ที่มันถูกสร้างมา ใช้ `if` ถ้าต้องการเงื่อนไข if และใช้ `&&` ถ้าต้องการตรรกะ AND +```` \ No newline at end of file From 0786abc5b05f3b35b489d391b7a6845dc07f3b05 Mon Sep 17 00:00:00 2001 From: Prasit Tongpradit Date: Wed, 27 Mar 2024 23:57:15 +0700 Subject: [PATCH 4/4] Add logical operators examples and explanations --- .../11-logical-operators/article.md | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index fe29cfb0f..8e2418a51 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -244,4 +244,44 @@ if (x > 0) alert( 'มากกว่าศูนย์!' ); ``` ถึงแม้การใช้ `&&` จะดูสั้นกว่า แต่ `if` จะชัดเจนและอ่านเข้าใจง่ายกว่า แนะนำให้ใช้แต่ละแบบตามวัตถุประสงค์ที่มันถูกสร้างมา ใช้ `if` ถ้าต้องการเงื่อนไข if และใช้ `&&` ถ้าต้องการตรรกะ AND -```` \ No newline at end of file +```` + +## ! (NOT) + +ตัวดำเนินการตรรกะ NOT ใช้สัญลักษณ์อัศเจรีย์ `!` + +รูปแบบการใช้งานค่อนข้างง่าย: + +```js +result = !value; +``` + +โดยตัวดำเนินการจะรับ operand เดียว และทำงานดังนี้: + +1. แปลง operand ให้เป็นประเภท boolean: `true/false` +2. คืนค่าตรงข้าม (invert) + +ตัวอย่างเช่น: + +```js run +alert( !true ); // false +alert( !0 ); // true +``` + +การใช้ NOT สองตัวติดกัน `!!` บางครั้งใช้เพื่อแปลงค่าให้เป็นประเภท boolean: + +```js run +alert( !!"non-empty string" ); // true +alert( !!null ); // false +``` + +นั่นคือ NOT ตัวแรกจะแปลงค่าเป็น boolean และคืนค่าตรงข้าม จากนั้น NOT ตัวที่สองก็จะ invert อีกครั้ง ในท้ายที่สุดเราจะได้การแปลงค่าเป็น boolean อย่างง่ายๆ + +มีอีกวิธีที่อ่านเข้าใจง่ายกว่าในการทำแบบเดียวกัน คือใช้ฟังก์ชันในตัว `Boolean`: + +```js run +alert( Boolean("non-empty string") ); // true +alert( Boolean(null) ); // false +``` + +ตัวดำเนินการ NOT `!` จะมีลำดับความสำคัญ (precedence) สูงสุดในบรรดาตัวดำเนินการตรรกะทั้งหมด ดังนั้นมันจะถูกประมวลผลก่อนเสมอ ก่อนที่จะไปประมวลผล `&&` หรือ `||` \ No newline at end of file