φυβλαςのβλογ
บล็อกของ 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)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

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

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月

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

ไทย

日本語

中文