Skip to content

บทที่ 04 — Control Flow: ควบคุมการทำงานของโปรแกรม

← บทที่ 03 | สารบัญ | บทที่ 05: Functions →

จนถึงตอนนี้ โปรแกรมเราทำงาน "บนลงล่าง" ทีละบรรทัด — บทนี้สอนวิธี "ควบคุม" การทำงาน:

  • ตัดสินใจ — ถ้าเงื่อนไขนี้จริงให้ทำอย่างหนึ่ง ไม่จริงทำอีกอย่าง
  • วนซ้ำ — ทำงานเดิมซ้ำ ๆ หลายรอบ

อ่านจบบทนี้คุณจะ:

  • ใช้ if/else, switch ตัดสินใจได้
  • ใช้ loop ทุกชนิด — และรู้ว่าใช้อันไหนเมื่อไหร่
  • เข้าใจความต่างสำคัญระหว่าง for...of กับ for...in (มือใหม่พลาดบ่อย)
  • เขียนโค้ดที่อ่านง่ายด้วย early return

ใช้เวลา 2-3 ชั่วโมง


Part 1: if / else — การตัดสินใจ

1.1 พื้นฐาน

if แปลว่า "ถ้า" — ถ้าเงื่อนไขเป็นจริง ทำโค้ดในวงเล็บปีกกา:

javascript
let age = 20;

if (age >= 18) {
  console.log("คุณเป็นผู้ใหญ่");
}

เงื่อนไขใน ( ) ต้องให้ผลเป็น true หรือ false (หรือ truthy/falsy)

1.2 if / else — ถ้าไม่ก็...

else ต่อท้าย if เพื่อบอกว่า "ถ้าเงื่อนไขไม่จริง ให้ทำอะไรแทน" — ทำให้โปรแกรมเลือกทางได้สองทาง:

javascript
let age = 15;

if (age >= 18) {
  console.log("ผู้ใหญ่");
} else {
  console.log("ยังไม่บรรลุนิติภาวะ");
}

1.3 if / else if / else — หลายเงื่อนไข

javascript
let score = 75;

if (score >= 80) {
  console.log("เกรด A");
} else if (score >= 70) {
  console.log("เกรด B");
} else if (score >= 60) {
  console.log("เกรด C");
} else {
  console.log("ตก");
}

JavaScript เช็คจากบนลงล่าง — เจอเงื่อนไขแรกที่จริง ทำอันนั้นแล้วข้ามที่เหลือทั้งหมด

1.4 ⚠️ ใส่ปีกกา { } เสมอ

JavaScript อนุญาตให้เขียน if บรรทัดเดียวโดยไม่มีปีกกา:

javascript
if (debug) console.log("debug mode");

แต่มันเป็นกับดัก — ลองดู:

javascript
if (debug)
  console.log("a");
  console.log("b");        // ⚠️ บรรทัดนี้รันเสมอ! ไม่ได้อยู่ใน if

มือใหม่เห็นโค้ดเยื้องเข้ามา 2 บรรทัด คิดว่าทั้ง 2 อยู่ใน if — แต่ JavaScript มอง if ครอบแค่บรรทัดถัดไปบรรทัดเดียว

กฎทอง: ใส่ { } เสมอ แม้มีบรรทัดเดียว — ป้องกันบั๊กแบบนี้ และทำให้โค้ดสม่ำเสมอ

javascript
if (debug) {
  console.log("debug mode");
}

1.5 เงื่อนไขแบบ truthy/falsy

จำ truthy/falsy จากบทที่ 02 ได้ไหม — if ใช้กฎนั้น:

javascript
let name = "";

if (name) {                      // "" เป็น falsy → ไม่ทำ
  console.log("มีชื่อ");
} else {
  console.log("ยังไม่ใส่ชื่อ");    // อันนี้ทำ
}

ใช้เช็คว่า "มีค่าไหม":

javascript
if (user) { ... }                // user ไม่ใช่ null/undefined/falsy
if (items.length) { ... }        // array ไม่ว่าง (length ไม่ใช่ 0)
if (user != null) { ... }        // user ไม่ใช่ null และไม่ใช่ undefined
                                 // ⚠️ ตรงนี้ใช้ != (loose) ตั้งใจ — นี่เป็นข้อยกเว้นที่ยอมรับได้
                                 // เพราะ != null จับทั้ง null และ undefined พร้อมกันในบรรทัดเดียว
                                 // เทียบเท่า user !== null && user !== undefined

⚠️ ระวัง — if (count) จะเป็น false ถ้า count เป็น 0 (ทั้งที่ 0 อาจเป็นค่าที่ถูกต้อง) — ถ้าอยากเช็คแค่ "ไม่ใช่ null/undefined" ใช้ if (count != null)


Part 2: switch — เลือกหลายกรณี

เมื่อต้องเช็คค่าตัวแปรเดียวกับหลาย ๆ ค่า — switch อ่านง่ายกว่า if-else if ยาว ๆ

javascript
let day = "จันทร์";

switch (day) {
  case "เสาร์":
  case "อาทิตย์":
    console.log("วันหยุด");
    break;
  case "จันทร์":
  case "อังคาร":
  case "พุธ":
  case "พฤหัส":
  case "ศุกร์":
    console.log("วันทำงาน");
    break;
  default:
    console.log("วันอะไรไม่รู้");
}

อธิบาย:

  • switch (day) — เอาค่า day มาเทียบ
  • case "จันทร์": — ถ้า day === "จันทร์" ทำตรงนี้
  • break;สำคัญมาก — บอกให้ "ออกจาก switch" เมื่อทำ case นี้เสร็จ
  • default: — ถ้าไม่ตรง case ไหนเลย

2.1 ⚠️ ลืม break = บั๊ก fall-through (ไหลตกลงต่อไป case ถัดไป)

ถ้าลืม break — JavaScript จะ "ไหลต่อ" ไปทำ case ถัดไปด้วย:

javascript
let level = 1;

switch (level) {
  case 1:
    console.log("level 1");
    // ลืม break!
  case 2:
    console.log("level 2");      // ⚠️ อันนี้รันด้วย แม้ level เป็น 1!
    break;
}
// ผลลัพธ์: "level 1" และ "level 2"

ใส่ break ทุก case เสมอ ยกเว้นตั้งใจให้ไหลต่อ (เช่นกรณีหลาย case ทำเหมือนกัน — ดูตัวอย่าง "วันหยุด" ข้างบนที่ตั้งใจ fall-through)

2.2 ทางเลือกสมัยใหม่ — Object Map

แทน switch ด้วย object บางทีอ่านง่ายกว่า:

javascript
const messages = {
  success: "สำเร็จ",
  error: "เกิดข้อผิดพลาด",
  pending: "กำลังดำเนินการ",
};

let status = "error";
console.log(messages[status] ?? "สถานะไม่รู้จัก");      // "เกิดข้อผิดพลาด"

→ ถ้าแค่ "map ค่า → ค่า" ใช้ object. ถ้ามี logic ซับซ้อนในแต่ละกรณี ใช้ switch


Part 3: Loop — การวนซ้ำ

Loop ทำให้เราทำงานเดิมซ้ำ ๆ โดยไม่ต้องเขียนโค้ดซ้ำ JavaScript มี loop หลายแบบ — มาดูทีละอัน

3.1 for — loop พื้นฐาน

javascript
for (let i = 0; i < 5; i++) {
  console.log("รอบที่", i);
}
// รอบที่ 0
// รอบที่ 1
// รอบที่ 2
// รอบที่ 3
// รอบที่ 4

for มี 3 ส่วน คั่นด้วย ;:

javascript
for (เริ่มต้น ; เงื่อนไขที่ทำให้วนต่อ ; ทำหลังจบแต่ละรอบ) {

อธิบายตัวอย่างข้างบน:

  • let i = 0 — เริ่มต้น: สร้างตัวนับ i เริ่มที่ 0 (ทำครั้งเดียว)
  • i < 5 — เงื่อนไข: วนต่อตราบใดที่ i ยังน้อยกว่า 5 (เช็คก่อนทุกรอบ)
  • i++ — ทำหลังจบรอบ: เพิ่ม i ขึ้น 1

ลำดับการทำงาน: ตั้ง i=0 → เช็ค 0<5✓ → ทำงาน → i++(เป็น 1) → เช็ค 1<5✓ → ... → i=5 → เช็ค 5<5✗ → จบ

3.2 while — วนตราบใดที่...

while วนตราบใดที่เงื่อนไขยังจริง:

javascript
let count = 0;
while (count < 5) {
  console.log(count);
  count++;                 // ⚠️ ต้องมีบรรทัดที่ทำให้เงื่อนไขเป็นเท็จในที่สุด
}

⚠️ ระวัง infinite loop (วนไม่จบ) — ถ้าลืม count++ เงื่อนไข count < 5 จะจริงตลอด → loop ไม่จบ → โปรแกรมค้าง

ใช้ while เมื่อ "ไม่รู้จะวนกี่รอบ" — เช่นวนจนกว่าผู้ใช้จะตอบถูก

3.3 do...while — ทำก่อนเช็คทีหลัง

do...while ต่างจาก while ตรงที่ — มัน ทำงานอย่างน้อย 1 รอบเสมอ ก่อนเช็คเงื่อนไข เหมาะกับสถานการณ์แบบ "ทำ แล้วถามว่าจะวนต่อไหม":

javascript
// ตัวอย่างง่ายๆ — สุ่มจนกว่าจะได้เลขที่ต้องการ
let num;
do {
  num = Math.floor(Math.random() * 6) + 1;     // สุ่ม 1-6
  console.log("ทอย:", num);
} while (num !== 6);
console.log("ได้ 6 แล้ว!");

ตัวอย่างถามผู้ใช้ใน Node.js (ใช้ readline/promises ของ Node):

ต้องการ ES module — บันทึกเป็น .mjs หรือตั้ง "type": "module" ใน package.json เพราะ await ต้องอยู่ใน async function หรือ ES module เท่านั้น

อย่าเพิ่งกังวลกับ async/await ตรงนี้ — จะเรียนเต็มในบทที่ 09 ตอนนี้แค่รู้ว่ามันมีวิธีถามผู้ใช้ใน terminal ได้

javascript
import { createInterface } from "node:readline/promises";
import { stdin, stdout } from "node:process";

async function main() {
  const rl = createInterface({ input: stdin, output: stdout });
  let answer;
  do {
    answer = await rl.question("ตอบคำถาม: ");
  } while (answer !== "ถูก");
  rl.close();
}
main();

หมายเหตุ: prompt() ที่หลายตำราใช้ มีเฉพาะใน เบราว์เซอร์ — ใน Node.js จะ ReferenceError: prompt is not defined ต้องใช้ readline/promises แทน (หรือไลบรารีอย่าง prompts, inquirer)

ใช้น้อย — ส่วนใหญ่ใช้ while ก็พอ

3.4 for...of — วนค่าใน array (ใช้บ่อยที่สุด)

for...of วนผ่าน "ค่า" ในสิ่งที่วนได้ (array, string, ฯลฯ):

javascript
const fruits = ["แอปเปิล", "กล้วย", "ส้ม"];

for (const fruit of fruits) {
  console.log(fruit);
}
// แอปเปิล
// กล้วย
// ส้ม

อ่านง่ายกว่า for ปกติมาก — ไม่ต้องจัดการตัวนับ i เอง

วนผ่าน string ก็ได้:

javascript
for (const char of "ABC") {
  console.log(char);       // A, B, C
}

ถ้าอยากได้ตำแหน่ง (index) ด้วย — ใช้ .entries() (method ที่คืน iterator ของคู่ [index, value] ทีละคู่):

javascript
for (const [index, fruit] of fruits.entries()) {
  console.log(index, fruit);     // 0 แอปเปิล, 1 กล้วย, 2 ส้ม
}

(สังเกต [index, fruit] คือ destructuring จากบทที่ 03 — แกะคู่ [index, value] เป็น 2 ตัวแปร)

3.5 for...in — วน "key" ของ object

ถ้าอยากวนดูทุก property ของ object ใช้ for...in ซึ่งจะให้ "key" (ชื่อ property) มาทีละตัว แล้วเราเข้าถึงค่าด้วย object[key] (ต่างจาก for...of ที่ใช้กับ array/ค่าในลำดับ):

javascript
const user = { name: "Alice", age: 25, city: "Bangkok" };

for (const key in user) {
  console.log(key, "=", user[key]);
}
// name = Alice
// age = 25
// city = Bangkok

3.6 ⚠️ for...of vs for...in — อย่าสับสน!

นี่เป็นจุดที่มือใหม่พลาดบ่อยมาก — จำให้แม่น:

for...offor...in
วนอะไรค่า (value)key (ชื่อ property/index)
ใช้กับarray, stringobject
javascript
const arr = ["a", "b", "c"];

for (const x of arr) console.log(x);     // a, b, c   (ค่า)
for (const x in arr) console.log(x);     // "0", "1", "2"   (index — เป็น string เพราะ for...in คืน key ที่เป็น string เสมอ)

⚠️ จุดสำคัญ: for...in คืน key เป็น string เสมอ ไม่ใช่ number

ดังนั้น x + 1 กับ array จะกลายเป็นการต่อข้อความ (string concatenation) เช่น "01", "11", "21" แทนที่จะเป็นตัวเลข 1, 2, 3 — นี่คืออีกเหตุผลที่ไม่ควรใช้ for...in กับ array

⚠️ อย่าใช้ for...in กับ array — มันมีปัญหา:

javascript
const arr = ["a", "b", "c"];
arr.extra = "เพิ่มมา";              // เผลอเพิ่ม property

for (const x in arr) {
  console.log(x);                  // 0, 1, 2, extra ← "extra" โผล่มาด้วย!
}

→ จำง่าย ๆ:

  • array → ใช้ for...of (หรือ array methods — บทที่ 07)
  • object → ใช้ for...in (หรือ Object.keys() — บทที่ 06)

3.7 forEach — method ของ array

array มี method forEach ที่วนผ่านแต่ละตัว:

javascript
const fruits = ["แอปเปิล", "กล้วย", "ส้ม"];

fruits.forEach((fruit, index) => {
  console.log(index, fruit);
});

forEach รับ function เข้าไป แล้วเรียก function นั้นกับทุกตัวใน array

⚠️ ข้อจำกัดของ forEach:

  • ใช้ break ไม่ได้ — หยุดกลางคันไม่ได้
  • ใช้กับ await ไม่ได้ตามที่คาด (เรื่อง async บทที่ 09) — forEach ยอมรับ async callback ได้โดยไม่ error แต่จะไม่รอ (await) ผลลัพธ์ของแต่ละตัวก่อนไปตัวถัดไป — เป็นกับดักเงียบ ไม่ใช่ error ทันที และถ้า callback เกิด error จะกลายเป็น error ที่ไม่มีใครจับ (unhandled promise rejection) ซึ่งอาจเงียบหายไปโดยไม่มีใครรู้ — เรื่องนี้จะเข้าใจเต็มที่หลังเรียนบทที่ 09

→ ถ้าต้องการ break หรือ await ใช้ for...of แทน. forEach เหมาะกับงานง่าย ๆ ที่ไม่ต้องหยุดกลางคัน

(map, filter, reduce — array methods ที่ทรงพลังกว่า เรียนบทที่ 07)


Part 4: break กับ continue

ภายใน loop เราควบคุมการวนได้ด้วย 2 คำสั่ง

4.1 break — ออกจาก loop ทันที

javascript
for (let i = 0; i < 100; i++) {
  if (i === 5) {
    break;                 // เจอ i=5 → ออกจาก loop เลย
  }
  console.log(i);          // 0, 1, 2, 3, 4
}

ใช้เมื่อ "เจอสิ่งที่หา แล้วไม่ต้องวนต่อ"

4.2 continue — ข้ามไปรอบถัดไป

javascript
for (let i = 0; i < 10; i++) {
  if (i % 2 !== 0) {
    continue;              // ถ้า i เป็นเลขคี่ → ข้ามไปรอบถัดไป
  }
  console.log(i);          // 0, 2, 4, 6, 8 (เฉพาะเลขคู่)
}

continue ไม่ได้ออกจาก loop — แค่ "ข้ามโค้ดที่เหลือในรอบนี้ ไปเริ่มรอบใหม่"


Part 5: Early Return (การ return ออกเร็ว — จัดการกรณีพิเศษก่อน) — เขียนโค้ดที่อ่านง่าย

นี่ไม่ใช่ syntax ใหม่ — แต่เป็น "เทคนิคการเขียน" ที่ทำให้โค้ดอ่านง่ายมาก

ปัญหา — โค้ดที่ if ซ้อนกันลึก ๆ อ่านยาก:

javascript
// ❌ ซ้อนลึก — อ่านยาก
function processUser(user) {
  if (user) {
    if (user.isActive) {
      if (user.balance > 0) {
        // ทำงานจริง... อยู่ลึกมาก
        return "ดำเนินการสำเร็จ";
      } else {
        return "ยอดเงินไม่พอ";
      }
    } else {
      return "บัญชีถูกระงับ";
    }
  } else {
    return "ไม่มีผู้ใช้";
  }
}

แก้ด้วย early return — เช็คกรณีที่ "ผิด" ก่อน แล้ว return ออกไปเลย:

javascript
// ✅ early return — อ่านง่ายกว่ามาก
function processUser(user) {
  if (!user) return "ไม่มีผู้ใช้";
  if (!user.isActive) return "บัญชีถูกระงับ";
  if (user.balance <= 0) return "ยอดเงินไม่พอ";

  // ถึงตรงนี้ = ผ่านทุกเงื่อนไขแล้ว — ทำงานจริงได้เลย ไม่ต้องเยื้องลึก
  return "ดำเนินการสำเร็จ";
}

แนวคิด: "จัดการกรณีพิเศษ/ผิดพลาดให้เสร็จก่อน แล้วค่อยทำงานหลัก" — ทำให้โค้ดหลักไม่ต้องเยื้องลึก อ่านเป็นลำดับ

(ใช้ได้กับ function — เรื่อง function อยู่บทที่ 05)


Part 6: Iterator + Generator (ขั้นสูง — รู้จักไว้)

🚀 โซนขั้นสูง — ข้ามได้

Part นี้ (Iterator = ตัววนซ้ำ, Generator = ฟังก์ชันที่หยุดกลางคันได้) เป็นเรื่องขั้นสูงที่มือใหม่ ยังไม่จำเป็นต้องใช้ — อ่านผ่าน ๆ พอรู้ว่า "มี" ก็พอ ข้ามไป Part 7 ได้เลยถ้ายังงง ไม่กระทบการเรียนบทอื่น

คำศัพท์ที่จะเจอใน Part นี้:

คำความหมาย
iterable (สิ่งที่วนได้)object ที่ for...of วนได้ เช่น array, string, Map, Set
iterator (ตัววนซ้ำ)object ที่มี method .next() คืนค่าทีละตัว
generator (ตัวสร้างลำดับ)function พิเศษที่หยุดกลางคันแล้วทำต่อได้
yield (ส่งค่าออก/หยุด)คำสั่งใน generator ที่ "คืนค่าแล้วหยุดรอ"

ส่วนนี้เป็น concept (แนวคิด) ขั้นสูงขึ้นมาหน่อย — มือใหม่อ่านผ่าน ๆ ได้ จะกลับมาเข้าใจลึกตอนเรียนบทหลัง

6.1 ทำไม for...of วน array ได้

for...of วน array, string, Map, Set ได้ — เพราะของพวกนี้เป็น "iterable (สิ่งที่วนได้)"

6.2 Generator — function ที่ "หยุดได้"

ปกติ function ทำงานจนจบแล้วคืนค่า — แต่ generator เป็น function พิเศษที่ "หยุดกลางคันแล้วทำต่อได้":

javascript
function* counter() {        // function* (มีดอกจัน) = generator
  yield 1;                   // yield = "หยุดตรงนี้ คืนค่า 1 ออกไป"
  yield 2;
  yield 3;
}

for (const n of counter()) {
  console.log(n);            // 1, 2, 3
}

ประโยชน์ — สร้างลำดับที่ยาวมาก (หรือไม่รู้จบ) โดยไม่ต้องเก็บทั้งหมดใน memory:

javascript
function* naturalNumbers() {
  let n = 1;
  while (true) {             // วนไม่รู้จบ — แต่ไม่ค้าง! เพราะ yield หยุดได้
    yield n;
    n++;
  }
}

const gen = naturalNumbers();
console.log(gen.next().value);   // 1
console.log(gen.next().value);   // 2
console.log(gen.next().value);   // 3

⚠️ อย่ารัน for (const n of naturalNumbers()) console.log(n); ตรง ๆ — generator ตัวนี้ไม่มีวันจบ จะพิมพ์เลขไม่หยุดรัว ๆ (ไม่ใช่ค้างเงียบ ๆ) กิน CPU/หน่วยความจำเพิ่มเรื่อย ๆ ต้องใช้ break หรือเรียก .next() ทีละครั้งเอง ถ้าโปรแกรมพิมพ์ไม่หยุดแล้ว กด Ctrl+C เพื่อหยุดการทำงาน

ตอนนี้แค่รู้จักว่ามี — ใช้จริงไม่บ่อยสำหรับมือใหม่


Part 7: ข้อควรระวังเรื่อง Performance

มือใหม่ไม่ต้องกังวลเรื่อง performance ของ loop มาก — แต่รู้ไว้:

  • for ธรรมดา เร็วสุด (เล็กน้อย)
  • for...of เร็วรองลงมา — และอ่านง่าย
  • forEach, map, filter มี overhead (ค่าใช้จ่ายเพิ่ม — ช้าลงนิดหน่อย) เพราะต้องเรียก function ทุกรอบ — แต่อ่านง่าย

ในงานจริง 99% — ความต่างนี้ไม่สำคัญเลย → เลือกอันที่อ่านง่ายที่สุด ไม่ใช่อันที่เร็วที่สุด


Part 8: Lab — ลงมือทำ

Lab 1: FizzBuzz (โจทย์คลาสสิก)

วน 1 ถึง 20 — ถ้าหาร 3 ลงตัวพิมพ์ "Fizz", หาร 5 ลงตัวพิมพ์ "Buzz", หารทั้ง 3 และ 5 พิมพ์ "FizzBuzz", นอกนั้นพิมพ์เลข:

javascript
for (let i = 1; i <= 20; i++) {
  if (i % 15 === 0) {
    console.log("FizzBuzz");
  } else if (i % 3 === 0) {
    console.log("Fizz");
  } else if (i % 5 === 0) {
    console.log("Buzz");
  } else {
    console.log(i);
  }
}

(สังเกต — ต้องเช็ค % 15 ก่อน เพราะถ้าเช็ค % 3 ก่อนจะไม่มีทางถึง FizzBuzz)

Lab 2: หาผลรวมและค่าเฉลี่ย

ฝึกใช้ for...of วน array เพื่อสะสมผลรวม แล้วหารด้วยจำนวนสมาชิกเพื่อหาค่าเฉลี่ย — แพตเทิร์น "วนเพื่อสะสมค่า" ที่ใช้บ่อยมาก:

javascript
const scores = [85, 92, 78, 90, 88];

let sum = 0;
for (const score of scores) {
  sum += score;
}
const average = sum / scores.length;

console.log("ผลรวม:", sum);
console.log("ค่าเฉลี่ย:", average);

Lab 3: วน object

ฝึกใช้ for...in วน object เพื่อแสดงและสะสมค่าของแต่ละ property — รวมความรู้เรื่องวน key เข้ากับการสะสมผลรวม:

javascript
const prices = { apple: 30, banana: 15, orange: 25 };

let total = 0;
for (const fruit in prices) {
  console.log(`${fruit}: ${prices[fruit]} บาท`);
  total += prices[fruit];
}
console.log("รวม:", total, "บาท");

Lab 4: ฟังก์ชัน validate ด้วย early return

javascript
function validatePassword(password) {
  if (!password) return "กรุณากรอกรหัสผ่าน";
  if (password.length < 8) return "รหัสผ่านต้องยาวอย่างน้อย 8 ตัว";
  if (!/[0-9]/.test(password)) return "รหัสผ่านต้องมีตัวเลข";   // /[0-9]/ คือ regex — ดูคำอธิบายข้างล่าง
  return "รหัสผ่านใช้ได้";
}

console.log(validatePassword(""));            // กรุณากรอก...
console.log(validatePassword("abc"));         // ต้องยาว...
console.log(validatePassword("abcdefgh"));    // ต้องมีตัวเลข
console.log(validatePassword("abcdef12"));    // ใช้ได้

เกร็ดเรื่อง /[0-9]/.test(password) — นี่คือ regex (regular expression, นิพจน์ปกติ — เรียนละเอียดบทที่ 08)

  • /[0-9]/ หมายถึง "ตัวอักษรใดก็ได้ที่เป็นเลข 0-9"
  • .test(string) คืน true ถ้าเจอ pattern นั้นใน string
  • รวมแล้ว = "ใน password มีตัวเลขอย่างน้อย 1 ตัวไหม"

ถ้ายังไม่อยากใช้ regex ใช้แบบนี้แทนได้:

javascript
// วนดูทีละตัวอักษร ตรวจว่ามีเลข 0-9 อยู่ไหม
const digits = "0123456789";
const hasDigit = password.split("").some(c => digits.includes(c));
if (!hasDigit) return "รหัสผ่านต้องมีตัวเลข";

หมายเหตุด้านความปลอดภัย: Lab นี้สอนแค่ early return — กฎรหัสผ่านจริงในงานโปรดักชันมักต้องเช็คตัวพิมพ์ใหญ่, อักขระพิเศษ, ไม่ตรงกับ password ทั่วไป (ใช้ list เช่น zxcvbn) ฯลฯ อย่าก็อปไปใช้จริงตรง ๆ


Part 9: Checkpoint

  1. ทำไมต้องใส่ { } ใน if เสมอ แม้มีบรรทัดเดียว?
  2. switch ลืม break เกิดอะไรขึ้น?
  3. while ต่าง do...while ยังไง?
  4. for...of วนอะไร? for...in วนอะไร?
  5. ทำไมไม่ควรใช้ for...in กับ array?
  6. forEach มีข้อจำกัดอะไร 2 อย่าง?
  7. break ต่าง continue ยังไง?
  8. Early return ช่วยให้โค้ดดีขึ้นยังไง?
  9. Infinite loop เกิดจากอะไร? ป้องกันยังไง?
  10. ใน FizzBuzz ทำไมต้องเช็ค % 15 ก่อน % 3?

Part 10: สรุปบทนี้

  • if/else if/else — ตัดสินใจ — ใส่ { } เสมอ
  • switch — เลือกหลายกรณี — ใส่ break ทุก case
  • for — loop พื้นฐาน มีตัวนับ / while — วนตราบใดที่เงื่อนไขจริง
  • for...of — วน ค่า (ใช้กับ array, string) — ใช้บ่อยสุด
  • for...in — วน key (ใช้กับ object) — อย่าใช้กับ array
  • forEach — method ของ array — แต่ break/await ไม่ได้
  • break ออกจาก loop / continue ข้ามรอบ
  • Early return — เช็คกรณีผิดก่อน return ออก → โค้ดไม่เยื้องลึก อ่านง่าย

บทต่อไป — Functions เชิงลึก รวมถึง closure และ this (จุดสำคัญที่สุดของ JavaScript)


← บทที่ 03 | สารบัญ | บทที่ 05: Functions →