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



javascript เบื้องต้น บทที่ ๘: การทำซ้ำด้วย while และ for
เขียนเมื่อ 2019/07/31 23:12
แก้ไขล่าสุด 2024/03/28 23:05


โครงสร้างการวนซ้ำ

บ่อยครั้งที่ในโปรแกรมเราต้องการให้มีการทำงานอะไรบางอย่างที่ทำซ้ำหลายรอบ

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

วิธีการเขียนโปรแกรมให้วนซ้ำมีอยู่หลายวิธี ในบทนี้จะแนะนำ ๓ แบบที่เป็นพื้นฐานและนิยมใช้ คือ
  • while
  • do ๛ while
  • for
แต่ละวิธีสามารถใช้เพื่อทำการวนซ้ำได้เหมือนกัน แต่จะมีรายละเอียดต่างกันไป

นอกจากนี้ยังมีวิธีการอื่นที่ใช้ในการวนซ้ำอีก ซึ่งจะกล่าวถึงต่อไปในบทถัดๆไป



โครงสร้าง while

วิธีการใช้
while (เงื่อนไขที่จะให้ทำซ้ำต่อไป) {
  สิ่งที่ต้องการให้ทำซ้ำ
}

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

ตัวอย่างเช่น ต้องการไล่เรียงเลขคี่ตั้งแต่ 1 ถึง 11 อาจเขียนแบบนี้
var i = 1;
var s = "";
while (i < 12) {
  s += i + "~";
  i += 2;
}
alert(s); // ได้ 1~3~5~7~9~11~

รอบแรก i จะเท่ากับ 1 ซึ่งน้อยกว่า 12 จึงเริ่มทำคำสั่งไปในรอบแรก แล้ว i ก็จะเพิ่มเป็น 3 แล้วเข้าสู่รอบใหม่ ตรวจดูเงื่อนไขใหม่ ยังน้อยกว่า 12 อยู่ก็ทำต่อ จากนั้นก็วนซ้ำไปเรื่อยๆ จนในรอบที่ ๖ เมื่อสิ้นสุดรอบ ค่าของ i กลายเป็น 13 จึงทำให้เงื่อนไข i<12 เป็นเท็จ จึงสิ้นสุดการวนซ้ำ



ระวังการวนซ้ำไม่สิ้นสุด

เมื่อมีการใช้โครงสร้างวนซ้ำ สิ่งที่ต้องระวังอยู่อย่างสม่ำเสมอก็คือ ต้องไม่ให้เกิดการวนซ้ำอย่างไม่สิ้นสุด หรือที่เรียกว่า "วังวนอนันต์" (infinite loop)

ยกตัวอย่างเช่น
var a = 0;
var i = 1;
while (i > 0) {
  a = a + i++;
}

กรณีนี้ รอบแรก i จะเป็น 1 ถัดมาเป็น 2, 3, 4, ... ไปเรื่อยๆ ไม่ว่าจะวนซ้ำไปกี่ครั้งเงื่อนไขใน while ก็จะยังคงเป็นจริงตลอด เพราะ i แต่ละรอบมีแต่จะยิ่งบวกเพิ่ม ไม่มีทางกลับมาน้อยกว่า 0 ได้ จึงเกิดการวนซ้ำตลอดไป

เมื่อเกิดเหตุการณ์แบบนี้ขึ้นจะทำให้เครื่องทำงานหนักอย่างต่อเนื่อง ให้รีบหาทางหยุดโค้ดโดยเร็ว

ถ้ารันโค้ดนี้โดยการเปิดหน้าเว็บในเบราว์เซอร์ก็ให้รีบปิดหน้านั้นทิ้งไป



การหยุดกลางคันด้วย break

บางครั้งเราอาจต้องการให้หยุดการทำซ้ำเมื่อเข้าเงื่อนไขบางอย่างที่ต้องการ โดยที่ไม่จำเป็นต้องเข้าเงื่อนไขที่กำหนดไว้ที่ด้านหลัง while

กรณีแบบนี้อาจใส่ if และ break ไว้ในโครงสร้างวนซ้ำ

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

ตัวอย่าง
var i = 1;
var s = "";
while (i < 12) {
  s += i + "฿";
  if (i == 7) break;
  i += 2;
}
alert(s); // ได้ 1฿3฿5฿7฿

แบบนี้พอวนซ้ำไปจน i กลายเป็น 7 ก็จะเจอ break แล้วหลุดออกจาก {} ทันที ไม่ต้องรอให้วนซ้ำจนหมดตามเงื่อนไขของ while

แต่หากไม่เข้าเงื่อนไขที่ทำให้โดน break เสียก่อน ก็วนซ้ำจนจบได้ตามปกติ
var i = 2;
var s = "";
while (i < 12) {
  s += i + "฿";
  if (i == 7) break;
  i += 2;
}
alert(s); // ได้ 2฿4฿6฿8฿10฿

นอกจากนี้ยังอาจเขียนวังวนในลักษณะที่ให้ break เป็นเงื่อนไขแทนใน while ได้ โดยปล่อย while เป็นจริงไปตลอดไป กรณีนี้เงื่อนไขที่ใส่จะตรงกันข้ามกับใส่ while โดยตรง เพราะจะเลิกวนเมื่อเงื่อนไขเป็นจริง
var i = 4;
var s = "";
while (1) {
  if (i > 15) break;
  s += i + "ㄣ";
  i += 3;
}
alert(s); // ได้ 4ㄣ7ㄣ10ㄣ13ㄣ


การใช้ continue

บางครั้งเราอาจเจอกรณีที่ต้องการให้สิ้นสุดการทำซ้ำในรอบนั้นแล้วข้ามไปรอบต่อไปทันทีเลย กรณีแบบนี้ให้ใช้ continue

continue ต่างจาก break ตรงที่ break จะหยุดออกจากโครงสร้างส่วนภายในปีกกาที่วนซ้ำไปเลย แต่ continue แค่มาเริ่มวนรอบถัดไปต่อทันทีเท่านั้น

ตัวอย่าง
var i = 1;
var s = "";
while (i < 27) {
  i += 3;
  if (i > 7 && i < 21) continue;
  s += i + "ㄐ";
}
alert(s); // ได้ 4ㄐ7ㄐ22ㄐ25ㄐ28ㄐ

แบบนี้เมื่อมีการวน พอค่า i อยู่ระหว่าง 7 ถึง 21 จะถูกข้ามไป ไม่มีการบวก s เพิ่ม แต่ i ก็ยังคงเพิ่มอยู่ พอถึง 21 ก็กลับมาบวก s ต่อ

ให้ระวังวังวนอนันต์ที่อาจเกิดจาก continue ด้วย เช่นเผลอวาง i++ ไว้หลัง continue แบบนี้
var i = 1;
var s = "";
while (i < 27) {
  if (i > 7 && i < 21) continue;
  i += 3;
  s += i + "ㄐ";
}

แบบนี้จะทำให้ i ไม่มีการบวกเพราะเจอ continue แล้วก็จะวนซ้ำไม่สิ้นสุด



วังวนซ้อน

สามารถสร้างโครงสร้างการวนซ้ำให้ซ้อนกันได้ เช่นซ้อนสองชั้นจะกลายเป็นแบบนี้
s = "";
var i = 1;
while (i < 5) {        // เริ่ม while วงนอก
  var j = 1;
  while (j < 4) {      // เริ่ม while วงใน
    s += "¡" + j + i;
    j++;
  }                    // สิ้นสุด while วงใน
  s += "ㄓ";
  i++;
}                      // สิ้นสุด while วงนอก
alert(s); // ได้ ¡11¡21¡31ㄓ¡12¡22¡32ㄓ¡13¡23¡33ㄓ¡14¡24¡34ㄓ

แบบนี้ในแต่ละรอบที่มีการวนซ้ำโดย while ด้านนอก ค่า i จะเปลี่ยนไปเรื่อยๆ ภายในแต่ละรอบนั้นจะมีการวนซ้ำด้วย while ด้านในซึ่งมีการเปลี่ยนค่า j ไปเรื่อยๆหลายครั้ง

โดยทั่วไปเมื่อเขียนโครงสร้างซ้อนจะมีการเคาะวรรคให้ร่นเข้าไปตามลำดับขั้นเพื่อให้เข้าใจได้ง่ายว่าตรงไหนอยู่ในวงในหรือวงนอก

โครงสร้าง while อาจจะซ้อนกี่ชั้นก็ได้ หลักการเหมือนกัน เช่น ซ้อนสามชั้นอาจเขียนได้แบบนี้
s = "";
var i = 1;
while (i < 5) {            // เริ่ม while วงนอกสุด
  var j = 1;
  while (j < 4) {          // เริ่ม while วงกลาง
    var k = 1;
    while (k < 3) {        // เริ่ม while วงในสุด
      s += "≈" + k + j + i;
      k++;
    }                      // สิ้นสุด while วงในสุด
    s += " × ";
    j++;
  }                        // สิ้นสุด while วงกลาง
  s += "\n";
  i++;
}                          // สิ้นสุด while วงนอกสุด
alert(s);
ได้
≈111≈211 × ≈121≈221 × ≈131≈231 × 
≈112≈212 × ≈122≈222 × ≈132≈232 × 
≈113≈213 × ≈123≈223 × ≈133≈233 × 
≈114≈214 × ≈124≈224 × ≈134≈234 × 



โครงสร้าง do while

นอกจากโครงสร้างวนซ้ำโดยใช้ while เฉยๆแล้ว ยังมีอีกรูปแบบที่ดูแล้วใกล้เคียงกัน คือ do๛while

ลักษณะจะคล้ายกับ while เปล่าๆ แต่ว่าจะขึ้นต้นด้วย do แล้วปิดท้ายด้วย while โครงสร้างเป็นแบบนี้
do {
  ส่วนที่ต้องการให้ทำซ้ำ;
} while (เงื่อนไขที่ให้ทำซ้ำต่อ);

ตัวอย่าง
var s = "";
var i = 0;
do {
  s += "|" + i + "|";
  i++;
} while (i < 9);
alert(s); // ได้ |0||1||2||3||4||5||6||7||8|

ที่แตกต่างก็คือ do๛while จะมีการทำรอบแรกก่อนแล้วค่อยดูเงื่อนไข ดังนั้นจึงมีการทำอย่างน้อยหนึ่งรอบแน่นอน แต่ while นั้นถ้าไม่เข้าเงื่อนไขตั้งแต่แรกก็จะไม่มีการทำเลยแม้แต่รอบเดียว



โครงสร้าง for

for เป็นโครงสร้างสำหรับวนซ้ำอีกแบบที่นิยมใช้กัน

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

โครงสร้างในการใช้
for (var ค่าเริ่มต้นของตัวแปร; เงื่อนไขการให้วนซ้ำ; ความเปลี่ยนแปลงในแต่ละรอบ) {
  ส่วนที่ต้องการให้ทำซ้ำ;
}

ตัวอย่าง
var s = "";
for (var i = 1; i < 41; i += 5) {
  s += i + "#";
}
alert(s); // ได้ 1#6#11#16#21#26#31#36#

การที่รวม ๓ สิ่งไว้ในวงเล็บหลัง for ทั้งหมดทำให้เขียนได้สั้นกว่าการใช้ while แม้ว่าอาจดูแล้วเข้าใจยากกว่าสักหน่อย สำหรับผู้เริ่มฝึกหัด

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

นอกจากนี้ในจาวาสคริปต์ยังมีโครงสร้าง for ๛ in คือใช้ for ร่วมกับ in ซึ่งก็มีความหมายต่างไปจากการใช้ for เดี่ยวๆอีก และก็ต่างจาก for ๛ in ในไพธอนหรือรูบีด้วย จึงยิ่งสับสนได้ง่าย

เรื่องของ for ๛ in จะเขียนถึงในบทที่ ๒๓

และใน ES6 ยังมีโครงสร้าง for ๛ of เพิ่มเข้ามาอีก ซึ่งจะไปเขียนถึงในเนื้อหาส่วน ES6




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

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

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

หมวดหมู่

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

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

สารบัญ

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

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

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



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

  ค้นหาบทความ

  บทความแนะนำ

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

ไทย

日本語

中文