จาวาสคริปต์รองรับชุดคำสั่งขนาดย่อม ซึ่งส่วนใหญ่เป็นคำสั่งควบคุมที่คุณสามารถใช้สร้างปฏิสัมพันธ์ในหน้าเว็บได้หลากหลาย โดยในบทนี้จะกล่าวถึงภาพรวมของคำสั่งเหล่านี้
นิพจน์ก็เป็นคำสั่งแบบหนึ่ง ดูข้อมูลเกี่ยวกับนิพจน์ได้ที่ Expressions and Operators
ใช้เครื่องหมายเซมิโคลอน (;
) เพื่อแยกคำสั่งในโปรแกรมจาวาสคริปต์
ดูรายละเอียดของคำสั่งต่างๆในบทนี้ได้ที่ JavaScript Reference
บล็อกคำสั่ง
บล็อกคำสั่ง ใช้เพื่อจัดกลุ่มคำสั่ง โดยจำกัดขอบเขตบล็อกด้วยคู่วงเล็บปีกกา ดังนี้:
{ statement_1; statement_2; . . . statement_n; }
ตัวอย่าง
บล็อกคำสั่ง โดยทั่วไปใช้ร่วมกับคำสั่งควบคุมต่างๆ (เช่น if
, for
, while
)
while (x < 10){ x++; }
โดยที่, { x++; }
คือบล็อกคำสั่ง
เรื่องสำคัญ: จาวาสคริปต์ ไม่มี ขอบเขตบล็อก โดยตัวแปรที่ประกาศภายในบล็อกมีขอบเขตอยู่ในฟังก์ชันหรือสคริปต์ที่ครอบบล็อกนั้น และการให้ค่าตัวแปรเหล่านี้มีผลถึงข้างนอกบล็อกนั้นด้วย หรืออธิบายได้ว่า, บล็อกคำสั่งไม่สร้างขอบเขตตัวแปรขึ้น และถึงแม้ว่าจะสามารถใช้บล็อกคำสั่งโดยไม่มีคำสั่งควบคุมได้ คุณก็ไม่ควรทำแบบนั้นในจาวาสคริปต์ เพราะมันไม่ได้ทำงานแบบเดียวกับในภาษาซีหรือจาวาอย่างที่เราคิด ตัวอย่าง เช่น:
var x = 1; { var x = 2; } alert(x); // outputs 2
จะได้ค่า 2
เพราะว่าคำสั่ง var x
ในบล็อกอยู่ในขอบเขตเดียวกับ var x
นอกบล็อก แต่ถ้าเป็นในภาษาซีหรือจาวา, จะได้ค่าเป็น 1
คำสั่งเงื่อนไข
คำสั่งเงื่อนไข คือชุดคำสั่งที่จะทำงานเมื่อเงื่อนไขที่ระบุเป็นจริง โดยจาวาสคริปต์รองรับคำสั่งเงื่อนไขสองแบบ คือ if...else
และ switch
คำสั่ง if...else
ใช้คำสั่ง if
เมื่อต้องการให้คำสั่งที่กำหนด ทำงานเมื่อเงื่อนไขตรรกะเป็นจริง (true
) และอาจใช้ else
ได้ ถ้าต้องการให้อีกคำสั่งทำงานเมื่อเงื่อนไขเป็นเท็จ (false
) โดยคำสั่ง if
มีรูปแบบการใช้งานดังนี้:
if (condition) statement_1 [else statement_2]
โดย condition
เป็นนิพจน์ใดๆที่หาค่าได้เป็น true
หรือ false
(ดูคำอธิบายเรื่องวิธีการหาค่า true
และ false
ได้ที่ Boolean) ซึ่งถ้า condition
มึค่าเป็น true
จะทำให้ statement_1
ทำงาน และในทางตรงข้าม, statement_2
จะทำงานแทน โดยที่ statement_1
และ statement_2
สามารถเป็นคำสั่ง if
ซ้อนได้
คุณสามารถผสมคำสั่ง โดยใช้ else if
เมื่อต้องการทดสอบเงื่อนไขทีละขั้นได้ ดังนี้:
if (condition) statement_1 [else if (condition_2) statement_2] ... [else if (condition_n_1) statement_n_1] [else statement_n]
ถ้าต้องการให้หลายคำสั่งทำงานในเงื่อนไขเดียวกัน, ให้รวมคำสั่งเข้าด้วยกันในบล็อกคำสั่ง ({ ... }
) ซึ่งการใช้บล็อกคำสั่งอยู่เสมอเป็นวิธีการที่ดี โดยเฉพาะเมื่อใช้คำสั่ง if
ซ้อนกันหลายชั้น:
if (condition) { statement_1_runs_if_condition_is_true statement_2_runs_if_condition_is_true } else { statement_3_runs_if_condition_is_false statement_4_runs_if_condition_is_false }
if (x = y) { /* do the right thing */ }
ถ้าคุณจำเป็นต้องกำหนดค่าในนิพจน์เงื่อนไข, วิธีที่ใช้กันคือ ใส่วงเล็บครอบไปอีกชั้น เช่นตัวอย่างนี้:
if ((x = y)) { /* do the right thing */ }
ค่าต่อไปนี้ เมื่อนำมาหาค่าแล้วจะได้ค่า false
:
false
undefined
null
0
NaN
- สตริงว่าง (
""
)
สำหรับค่าอื่นๆ รวมทั้งอ็อบเจ็กต์ทุกตัว, เมื่อนำมาหาค่าในคำสั่งเงื่อนไข จะได้ค่า true
เสมอ
อย่าสับสนกับค่าข้อมูลตรรกะพื้นฐาน true
และ false
กับค่าที่ได้จากอ็อบเจกต์ Boolean ดังตัวอย่าง
var b = new Boolean(false); if (b) // this condition evaluates to true
Example
ในตัวอย่างต่อไปนี้, ฟังก์ชัน checkData
จะคืนค่า true
ถ้าอ็อบเจกต์ threeChar
มีข้อความยาวสามอักขระ, นอกจากนั้นจะแสดงคำเตือน และคืนค่า false
function checkData() { if (document.form1.threeChar.value.length == 3) { return true; } else { alert("Enter exactly three characters. " + document.form1.threeChar.value + " is not valid."); return false; } }
คำสั่ง switch
คำสั่ง switch
ทำงานโดยนำค่าของนิพจน์มาจับคู่กับค่าที่กำหนด ถ้าตรงกัน, โปรแกรมจะทำงานตามคำสั่งที่เกี่ยวข้อง คำสั่ง switch
มีรูปแบบการใช้ดังนี้:
switch (expression) { case label_1: statements_1 [break;] case label_2: statements_2 [break;] ... default: statements_def [break;] }
เริ่มจากโปรแกรมมองหาประโยค case
ที่มีค่าตรงกับค่าจากนิพจน์ (expression
) และข้ามไปทำงานที่ตำแหน่งนั้นตามคำสั่งที่กำหนด ถ้าไม่พบค่าที่ตรงกัน, โปรแกรมจะมองหาประโยค default
และทำงานที่ตำแหน่งนั้นตามคำสั่งที่กำหนด ถ้าไม่พบประโยค default
, โปรแกรมจะทำงานต่อที่ตำแหน่งถัดจากคำสั่ง switch
ซึ่งตามหลักการแล้ว, ประโยค default
ควรอยู่ท้ายสุด แต่ก็ไม่จำเป็นเสมอไป
คำสั่ง break
ที่ใส่ไว้ในประโยค case
จะทำให้โปรแกรมหยุดทำงานและออกจากคำสั่ง switch
แล้วทำงานต่อที่ตำแหน่งถัดจากคำสั่ง switch
แต่ถ้าไม่มี break
, โปรแกรมจะทำงานต่อที่คำสั่งถัดไปใน switch
ตัวอย่าง
ในตัวอย่างต่อไปนี้, ถ้า fruttype
มีค่าเป็น "Bananas"
โปรแกรมจะพบค่าที่ตรงกันในประโยค case "Bananas"
และข้ามไปทำงานที่ตำแหน่งนั้น จนถึงคำสั่ง break
โปรแกรมก็จะหยุดทำงานแล้วทำงานต่อที่ตำแหน่งถัดจากคำสั่ง switch
แต่ถ้าไม่มี break
, โปรแกรมจะทำงานต่อที่คำสั่งถัดมาในประโยค case "Cherries"
ด้วย
switch (fruittype) { case "Oranges": document.write("Oranges are $0.59 a pound.<br>"); break; case "Apples": document.write("Apples are $0.32 a pound.<br>"); break; case "Bananas": document.write("Bananas are $0.48 a pound.<br>"); break; case "Cherries": document.write("Cherries are $3.00 a pound.<br>"); break; case "Mangoes": case "Papayas": document.write("Mangoes and papayas are $2.79 a pound.<br>"); break; default: document.write("Sorry, we are out of " + fruittype + ".<br>"); } document.write("Is there anything else you'd like?<br>");
คำสั่งลูป
คำสั่งลูป คือชุดคำสั่งที่ทำงานซ้ำจนกระทั่งเงื่อนไขที่กำหนดเป็นจริง โดยจาวาสคริปต์รองรับคำสั่งลูป for
, do...while
, และ while
และป้ายชื่อคำสั่ง (ซึ่งไม่ใช่คำสั่งลูป แต่มักใช้คู่กัน) นอกจากนี้, คุณยังสามารถใช้คำสั่ง break
และ continue
กับคำสั่งลูปได้ด้วย
อีกคำสั่งหนึ่งคือ for...in
, เป็นคำสั่งที่ทำงานวนซ้ำเหมือนกัน แต่ใช้กับการจัดการอ็อบเจกต์ ดูเพิ่มเติมที่ Object Manipulation Statements
คำสั่งลูปทั้งหมด มีดังนี้:
- for Statement
- do...while Statement
- while Statement
- label Statement
- break Statement
- continue Statement
คำสั่ง for
คำสั่งลูป for
จะทำงานซ้ำจนกระทั่งเงื่อนไขที่กำหนดเป็นเท็จ (false
) โดย for
ในจาวาสคริปต์ทำงานคล้าย for
ในภาษาจาวาและซี ซึ่งมีรูปแบบการใช้งานดังนี้:
for ([initialExpression]; [condition]; [incrementExpression]) statement
เมื่อคำสั่ง for
ทำงาน, สิ่งที่เกิดขึ้นคือ:
- ถ้ามีนิพจน์
initialExpression
, จะมีการประมวลค่านิพจน์นี้ ซึ่งโดยทั่วไปจะใช้เพื่อกำหนดค่าเริ่มต้นให้กับตัวแปร ตัวเดียวหรือหลายตัว แต่ก็สามารถใช้กับนิพจน์ที่มีความซับซ้อน และใช้ประกาศตัวแปรได้ - ทำการประมวลค่านิพจน์
condition
, ถ้ามีค่าเป็นจริง (true
) คำสั่งในลูปทั้งหมดจะทำงาน แต่ถ้ามีค่าเท็จ (false
) ลูป for จะหยุดทำงาน และถ้าไม่มีนิพจน์condition
เลย, ค่าเงื่อนไขนี้จะถูกสมมุติให้เป็นจริง (true
) - คำสั่ง
statement
เริ่มทำงาน, ถ้าต้องการทำงานหลายคำสั่ง ต้องใช้บล็อกคำสั่ง (( ... )
) หุ้มอีกชั้น - ถ้ามีนิพจน์
incrementExpression
, จะมีการประมวลค่านิพจน์นี้ และกลับไปทำงานที่ขั้นตอนที่ 2
ตัวอย่าง
ฟังก์ชันต่อไปนี้ประกอบด้วยคำสั่ง for
ซึ่งใช้นับจำนวนตัวเลือกที่ถูกเลือกในรายการข้อมูล (อ็อบเจกต์ Select
ยอมให้เลือกได้หลายค่า) โดยคำสั่ง for
ประกาศตัวแปร i
และกำหนดค่าเริ่มต้นเป็นศูนย์ จากนั้นจะตรวจสอบว่า i
ยังมีค่าน้อยกว่าจำนวนตัวเลือกในอ็อบเจกต์ Select
แล้วจึงทำตามคำสั่ง if
ที่กำหนด และเพิ่มค่า i
ทีละหนึ่งทุกครั้งที่ครบลูป
<script> function howMany(selectObject) { var numberSelected = 0; for (var i = 0; i < selectObject.options.length; i++) { if (selectObject.options[i].selected) numberSelected++; } return numberSelected; } </script> <form name="selectForm"> <p> <strong>Choose some music types, then click the button below:</strong> <br/> <select name="musicTypes" multiple="multiple"> <option selected="selected">R&B</option> <option>Jazz</option> <option>Blues</option> <option>New Age</option> <option>Classical</option> <option>Opera</option> </select> </p> <p> <input type="button" value="How many are selected?" onclick="alert ('Number of options selected: ' + howMany(document.selectForm.musicTypes))"/> </p> </form>
คำสั่ง do...while
คำสั่ง do...while
จะทำงานซ้ำจนกระทั่งเงื่อนไขที่กำหนดเป็นเท็จ (false
) โดยมีรูปแบบการใช้งานดังนี้:
do statement while (condition);
คำสั่ง statement
จะทำงานหนึ่งครั้งก่อนที่จะมีการตรวจสอบเงื่อนไข ถ้าต้องการทำงานหลายคำสั่ง ต้องใช้บล็อกคำสั่ง ({ ... }
) หุ้มอีกชั้น เมื่อเงื่อนไข condition
เป็นจริง (true
), คำสั่ง statement
จะทำงานอีกครั้ง โดยทุกครั้งที่จบการทำงานจะทำการตรวจสอบเงื่อนไข เมื่อเงื่อนไขเป็นเท็จ (false
), การทำงานจะหยุดและข้ามไปทำต่อที่คำสั่งถัดจาก do...while
ตัวอย่าง
ในตัวอย่างต่อไปนี้, ลูป do
จะทำงานซ้ำอย่างน้อยหนึ่งครั้ง และทำซ้ำอีกจนกระทั่ง i
มีค่าไม่น้อยกว่า 5
do { i += 1; document.write(i); } while (i < 5);
คำสั่ง while
คำสั่ง while
จะทำงานเมื่อเงื่อนไขที่กำหนดเป็นจริง (true
) โดยมีรูปแบบการใช้งานดังนี้:
while (condition) statement
ถ้าเงื่อนไขกลายเป็นเท็จ (false
), คำสั่งในลูปจะหยุดทำงานและข้ามไปทำงานต่อที่คำสั่งถัดจากลูป
การทดสอบเงื่อนไขจะเกิดขี้นก่อนคำสั่ง statement
ในลูปเริ่มทำงาน เมื่อเงื่อนไขเป็นจริง (true
), คำสั่ง statement
จะทำงาน และเงื่อนไขจะถูกทดสอบอีกครั้ง จนเมื่อเงื่อนไขเป็นเท็จ (false
) การทำงานจะหยุดและข้ามไปทำงานต่อที่คำสั่งถัดจาก while
ถ้าต้องการทำงานหลายคำสั่ง, ให้ใช้บล็อกคำสั่ง ({ ... }
) หุ้มอีกชั้น
ตัวอย่างที่ 1
ลูป while
ต่อไปนี้ จะทำงานซ้ำเมื่อ n
ยังน้อยกว่า 3
:
n = 0; x = 0; while (n < 3) { n++; x += n; }
ในแต่ละรอบของการทำซ้ำ, ลูปจะเพิ่มค่า n
และบวกค่าให้ x
, นั่นคือ x
และ n
จะมีค่าดังนี้:
- หลังจากผ่านรอบแรกไป:
n = 1
และx = 1
- หลังจากผ่านไปสองรอบ:
n = 2
และx = 3
- หลังจากผ่านไปสามรอบ:
n = 3
และx = 6
หลังจากจบรอบสาม, เงื่อนไขที่ n < 3
ไม่เป็นจริงอีกแล้ว, ลูปจึงหยุดทำงาน
ตัวอย่างที่ 2
เพื่อหลีกเลี่ยงการวนลูปแบบไม่สิ้นสุด, ต้องแน่ใจว่าเงื่อนไขในลูปจะกลายเป็นเท็จ (false
) ได้ในที่สุด มิเช่นนั้นลูปจะทำงานไม่หยุด เช่น คำสั่งในลูป while
ต่อไปนี้จะทำงานไปตลอดเพราะเงื่อนไขไม่เคยเป็นเท็จ (false
)
while (true) { alert("Hello, world"); }
ป้ายชื่อคำสั่ง
การกำหนดป้ายชื่อคำสั่ง คือการติดป้ายชื่อที่คำสั่งใดๆเพื่อช่วยให้คุณอ้างถึงมันได้จากที่ต่างๆในโปรแกรม ตัวอย่าง เช่น, คุณสามารถติดป้ายชื่อที่คำสั่งลูป และใช้คำสั่ง break
หรือ continue
เพื่อให้โปรแกรมหยุดการทำงานและออกจากลูป หรือทำงานต่อที่ลูปนั้น
รูปแบบการติดป้ายชื่อที่คำสั่ง มีวิธีดังนี้:
label : statement
โดย label
คือป้ายชื่อคำสั่ง ตั้งชื่อตามแบบตัวแปรในจาวาสคริปต์ ซึ่งไม่สามารถใช้คำสงวนได้ โดยคำสั่ง statement
ที่กำหนดคู่กับป้ายชื่อ label
จะเป็นคำสั่งแบบใดก็ได้
ตัวอย่าง
ในตัวอย่างนี้, markLoop
คือป้ายชื่อที่ตั้งให้ลูป while
markLoop: while (theMark == true) { doSomething(); }
คำสั่ง break
ใช้คำสั่ง break
เพื่อหยุดการทำงานในลูป, switch
, หรือใช้ร่วมกับป้ายชื่อคำสั่ง
- เมื่อคุณใช้
break
โดยไม่ระบุป้ายชื่อคำสั่ง, มันจะหยุดการทำงานของคำสั่งชั้นในสุดของwhile
,do-while
,for
, หรือswitch
ทันทีและข้ามออกมาทำงานในคำสั่งถัดไป - เมื่อคุณใช้
break
และระบุป้ายชื่อคำสั่ง, มันจะหยุดการทำงานของคำสั่งตามป้ายชื่อนั้น
รูปแบบของคำสั่ง break เป็นดังนี้:
break;
break label;
รูปแบบแรกจะหยุดการทำงานของลูปในสุด หรือใน switch, ส่วนแบบที่สอง จะหยุดการทำงานของคำสั่งทีี่มีป้ายชื่อ label
ตัวอย่างที่ 1:
ตัวอย่างต่อไปนี้ ทำงานซ้ำตามจำนวนสมาชิกในอาร์เรย์ จนกระทั่งพบตำแหน่งของสมาชิกที่มีค่าเท่ากับ theValue
for (i = 0; i < a.length; i++) { if (a[i] == theValue) break; }
ตัวอย่างที่ 2: หยุดทำงานของคำสั่งตามป้ายชื่อที่กำหนด
var x = 0; var z = 0 labelCancelLoops: while (true) { console.log("Outer loops: " + x); x += 1; z = 1; while (true) { console.log("Inner loops: " + z); z += 1; if (z === 10 && x === 10) { break labelCancelLoops; } else if (z === 10) { break; } } }
คำสั่ง continue
คำสั่ง continue
ใช้เพื่อเริ่มการทำงานใหม่ของคำสั่ง while
, do-while
, for
, หรือที่ป้ายชื่อคำสั่ง:
- เมื่อคุณใช้
continue
โดยไม่ระบุป้ายชื่อคำสั่ง, มันจะหยุดการทำงานรอบปัจจุบันที่ชั้นในสุดของคำสั่งwhile
,do-while
หรือคำสั่งfor
และเริ่มทำงานลูปใหม่ในรอบถัดไป ที่ตรงข้ามกับคำสั่งbreak
คือcontinue
จะไม่หยุดการทำงานของลูปทั้งหมด โดยในลูปwhile
, มันจะข้ามไปทำงานที่ตำแหน่งเงื่อนไข และในลูปfor
, มันจะข้ามไปทำงานที่ส่วนincrement-expression
- เมื่อคุณใช้
continue
กับป้ายชื่อคำสั่ง, มันจะถูกใช้กับคำสั่งลูปที่มีป้ายชื่อตามที่กำหนด
รูปแบบของคำสั่ง continue เป็นได้ดังนี้:
continue;
continue
label;
ตัวอย่างที่ 1
ตัวอย่างต่อไปนี้แสดง ลูป while ที่มีคำสั่ง continue ซึ่งจะทำงานเมื่อ i เป็น 3 นั่นคือ n จะมีค่าเป็น หนึ่ง, สาม, เจ็ด, และสิบสอง
i = 0; n = 0; while (i < 5) { i++; if (i == 3) continue; n += i; }
ตัวอย่างที่ 2
โปรแกรมต่อไปนี้ มีคำสั่ง while
ติดป้ายชื่อ checkiandj
ที่ภายในมีคำสั่ง while
ติดป้ายชื่อ checkj
เมื่อโปรแกรมทำงานถึงคำสั่ง continue
, โปรแกรมจะหยุดการทำงานรอบปัจจุบันของ checkj
และเริ่มทำงานในรอบถัดไป โดยทุกครั้งที่ทำงานถึง continue
โปรแกรมก็จะกลับไปเริ่มทำงาน checkj
รอบใหม่จนกระทั่งได้เงื่อนไขที่เป็นเท็จ (false
) ซึ่งทำให้โปรแกรมหลุดออกจากลูป checkj
เข้ามาในลูปใหญ่ checkiandj
และทำงานต่อจนจบลูป จากนั้น checkiandj
ก็
ทำงานซ้ำจนได้เงื่อนไขที่เป็นเท็จ (false
) ซึ่งทำให้โปรแกรมหลุดออกจากลูป checkiandj
และทำงานที่คำสั่งถัดไป
แต่ถ้า continue
ระบุป้ายชื่อ checkiandj
, โปรแกรมก็จะทำงานต่อที่ส่วนบนสุดของคำสั่ง checkiandj
แทน
checkiandj : while (i < 4) { document.write(i + "<br/>"); i += 1; checkj : while (j > 4) { document.write(j + "<br/>"); j -= 1; if ((j % 2) == 0) continue checkj; document.write(j + " is odd.<br/>"); } document.write("i = " + i + "<br/>"); document.write("j = " + j + "<br/>"); }
คำสั่งจัดการอ็อบเจกต์
จาวาสคริปต์ใช้คำสั่ง for...in
, for each...in
, และ with
ในการจัดการกับอ็อบเจกต์
คำสั่ง for...in
คำสั่ง for...in
จะทำงานซ้ำตามจำนวนคุณสมบัติของอ็อบเจกต์ โดยในแต่ละรอบ,ตัวแปรจะถูกกำหนดให้มีค่าเป็นคุณสมบัติของอ็อบเจกต์ทีละตัว และจาวาสคริปต์จะทำงานตามคำสั่งที่กำหนด จนครบตามจำนวนคุณสมบัติที่ต่างกันทั้งหมด โดยมีรูปแบบต่อไปนี้:
for (variable in object) { statements }
ตัวอย่าง
ฟังก์ชันต่อไปนี้ รับค่าพารามิเตอร์ อ็อบเจกต์และชื่ออ็อบเจกต์ โดยจะทำงานซ้ำตามคุณสมบัติทั้งหมดของอ็อบเจกต์ และคืนค่าสตริงที่แสดงชื่อคุณสมบัติกับค่าของมัน
function dump_props(obj, obj_name) { var result = ""; for (var i in obj) { result += obj_name + "." + i + " = " + obj[i] + "<br>"; } result += "<hr>"; return result; }
เมื่อใช้กับอ็อบเจกต์ car
ที่มีคุณสมบัติ make
และ model
, จะได้ค่า result
ดังนี้:
car.make = Ford car.model = Mustang
อา์เรย์
แม้ว่าเราอยากจะใช้วิธีนี้เพื่อวนซ้ำตามจำนวนสมาชิกของอ็อบเจกต์อาร์เรย์, แต่เนื่องจากคำสั่ง for...in
นอกจากจะทำงานซ้ำตามจำนวนสมาชิกอาร์เรย์แล้ว ยังทำงานซ้ำตามจำนวนคุณสมบัติของอาร์เรย์ด้วย ดังนั้นถ้าคุณแก้ไขอ็อบเจกต์อาร์เรย์ โดยเพิ่มคุณสมบัติหรือเมธอดเข้าไป, คำสั่ง for...in
จะทำงานซ้ำด้วยจำนวนครั้งที่รวมจำนวนคุณสมบัติและจำนวนสมาชิกเข้าด้วยกัน ด้วยเหตุนี้, วิธีที่ดีกว่าคือใช้คำสั่ง for
แบบปกติ และทำการวนซ้ำด้วยเลขตำแหน่งของสมาชิกในอาร์เรย์
คำสั่ง for each...in
for each...in
เป็นคำสั่งลูปที่เริ่มมีใน JavaScript 1.6 มีการทำงานคล้าย for...in
แต่ค่าที่วนซ้ำเป็นค่าของคุณสมบัติอ็อบเจกต์, ไม่ใช่ตัวคุณสมบัติ
var sum = 0; var obj = {prop1: 5, prop2: 13, prop3: 8}; for each (var item in obj) { sum += item; } print(sum); // prints "26", which is 5+13+8
คำอธิบาย
คำอธิบาย คือข้อความที่ผู้แต่งเขียนไว้เพื่ออธิบายการทำงานของสคริปต์ ซึ่งไม่ถูกอ่านโดยตัวแปลภาษา โดยจาวาสคริปต์รองรับคำอธิบายในแบบภาษาจาวาและซีพลัสพลัสดังนี้:
- คำอธิบายบรรทัดเดียว ให้เริ่มต้นด้วย
//
- คำอธิบายที่มีหลายบรรทัด ให้นำหน้าด้วย
/*
และปิดท้ายด้วย*/
ตัวอย่าง
ตัวอย่างต่อไปนี้ แสดงการเขียนคำอธิบายทั้งสองแบบ
// This is a single-line comment. /* This is a multiple-line comment. It can be of any length, and you can put whatever you want here. */
คำสั่งจัดการข้อผิดพลาด
คุณสามารถสร้างข้อผิดพลาดในโปรแกรม ด้วยการใช้คำสั่ง throw
และจัดการมันด้วยคำสั่ง try...catch
คุณยังสามารถใช้ try...catch
เพื่อจัดการข้อผิดพลาดของจาวาได้ (แม้ว่าจะมี bug 391642 ก็ตาม) โดยดูข้อมูลเพิ่มเติมได้ที่ Handling Java Exceptions in JavaScript และ JavaScript to Java Communication
ชนิดของข้อผิดพลาด
เราสามารถสร้างข้อผิดพลาดจากอ็อบเจกต์ชนิดใดก็ได้ แต่อย่างไรก็ตาม, อ็อบเจกต์ทุกตัวไม่ได้ถูกสร้างมาให้เท่าเทียมกัน ในกรณีทั่วไปอาจใช้แค่ตัวเลขหรือสตริงแทนข้อผิดพลาดได้ แต่เพิ่อประสิทธิภาพที่ดีกว่า เรามักจะใช้รูปแบบข้อผิดพลาดที่สร้างขึ้นโดยเฉพาะดังนี้:
คำสั่ง throw
ใช้คำสั่ง throw
เพื่อสร้างข้อผิดพลาด โดยให้ระบุนิพจน์แทนข้อผิดพลาด คู่กับคำสั่งดังนี้:
throw expression;
คุณอาจสร้างข้อผิดพลาดด้วยนิพจน์แบบใดก็ได้ ไม่ใช่แค่นิพจน์ของข้อมูลแบบใดแบบหนึ่งเท่านั้น ในโค้ดต่อไปนี้แสดงการสร้างข้อผิดพลาดด้วยข้อมูลที่แตกต่างชนิดกัน
throw "Error2"; //String type throw 42; //Number type throw true; //Boolean type throw {toString: function() { return "I'm an object!"; } };
catch
โดยตัวอย่างต่อไปนี้ มีการสร้างอ็อบเจกต์ myUserException
ที่มีชนิด UserException
และใช้ในคำสั่ง throw
// Create an object type UserException function UserException (message){ this.message=message; this.name="UserException"; } // Make the exception convert to a pretty string when used as a string (e.g. by the error console) UserException.prototype.toString = function (){ return this.name + ': "' + this.message + '"'; } // Create an instance of the object type and throw it throw new UserException("Value too high");
คำสั่ง try...catch
คำสั่ง try...catch
กำหนดบล็อกของคำสั่งที่จะทำงาน และกำหนดการตอบสนองต่อข้อผิดพลาดหนึ่งชนิดขึ้นไป โดยเมื่อมีข้อผิดพลาดเกิดขึ้น, คำสั่ง try...catch
ก็สามารถจัดการมันได้
คำสั่ง try...catch
ประกอบด้วย บล็อก try
ที่มีคำสั่งหนึ่งคำสั่งหรือมากกว่า และบล็อก catch
มากกว่าหนึ่งหรือไม่มีเลย ในบล็อกนี้จะมีคำสั่งที่ระบุว่าให้ทำอะไรถ้ามีข้อผิดพลาดเกิดขึ้นในบล็อก try นั่นคือคุณต้องการให้คำสั่งในบล็อก try
ทำงานสำเร็จ, แต่เมื่อทำไม่สำเร็จ คุณต้องการส่งต่อการทำงานไปที่บล๊อก catch
โดยเมื่อคำสั่งใดๆในบล็อก try
(หรือในการเรียกใช้ฟังก์ชันจากภายในบล็อก try
) สร้างข้อผิดพลาดขึ้น การทำงานของโปรแกรมจะข้ามไปที่บล็อก catch
ทันที แต่ถ้าไม่มีข้อผิดพลาดเกิดขึ้นในบล็อก try
, โปรแกรมจะข้ามบล็อก catch
ไป และจากนั้นบล๊อก finally
จะทำงานหลังจากบล็อก try
และ catch
ทำงานจบแล้ว ก่อนที่จะทำงานในคำสั่งถัดจากคำสั่ง try...catch
ต่อไป
ตัวอย่างต่อไปนี้ แสดงการใช้คำสั่ง try...catch
โดยตัวอย่างเรียกใช้ฟังก์ชันซึ่งรับชื่อเดือนจากอาร์เรย์ตามค่าเดือนที่ส่งให้ฟังก์ชัน ถ้าค่านี้ไม่สอดคล้องกับจำนวนเดิอน (1-12), จะเกิดข้อผิดพลาดขึ้นเป็นข้อความ "InvalidMonthNo"
และคำสั่งในบล็อก catch
จะกำหนดค่าให้ ตัวแปร monthName
เป็น unknown
function getMonthName (mo) { mo=mo-1; // Adjust month number for array index (1=Jan, 12=Dec) var months=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul", "Aug","Sep","Oct","Nov","Dec"); if (months[mo] != null) { return months[mo] } else { throw "InvalidMonthNo" //throw keyword is used here } } try {// statements to try monthName=getMonthName(myMonth) // function could throw exception } catch (e) { monthName="unknown" logMyErrors(e) // pass exception object to error handler }
บล็อก catch
คุณสามารถใช้บล็อก catch
เพื่อจัดการข้อผิดพลาดที่อาจเกิดขึ้นในบล็อก try
ได้
catch (catchID) { statements }
บล็อก catch
กำหนดชื่อตัวแปร (catchID
ในรูปแบบด้านบน) ซึ่งเก็บค่าที่มาจากคำสั่ง throw
คุณสามารถใช้ตัวแปรนี้เพื่อดึงข้อมูลเกี่ยวกับข้อผิดพลาดที่เกิดขึ้นได้ โดยจาวาสคริปต์จะสร้างตัวแปรนี้เมื่อบล็อก catch
เริ่มทำงาน และหลังจากที่บล็อก catch
ทำงานเสร็จแล้ว ตัวแปรนี้จะหายไป
ตัวอย่าง, โค้ดต่อไปนี้ทำให้เกิดข้อผิดพลาดขึ้น เมื่อมีข้อผิดพลาดเกิดขึ้น การทำงานจะถูกโอนไปที่บล๊อก catch
try { throw "myException" // generates an exception } catch (e) { // statements to handle any exceptions logMyErrors(e) // pass exception object to error handler }
บล็อก finally
บล็อก finally
ประกอบด้วย ชุดคำสั่งที่ทำงานหลังจากบล็อก try
และ catch
ทำงานแล้ว ก่อนที่คำสั่งถัดจาก try...catch
จะทำงาน โดยบล็อก finally
จะทำงานไม่ว่าจะมีข้อผิดพลาดเกิดขึ้นหรือไม่ ซึ่งคำสั่งในบล็อก finally
นี้จะทำงานแม้ว่าบล๊อก catch
จะไม่ได้ทำงานก็ตาม
คุณสามารถใช้บล็อก finally
เพื่อให้สคริปต์ทำงานจนจบได้แม้จะมีข้อผิดพลาดเกิดขึ้น ตัวอย่าง เช่น, คุณอาจจำเป็นต้องปลด resource
เมื่อสคริปต์ทำงานจบ ในตัวอย่างต่อไปนี้ เมื่อเปิดไฟล์และทำงานกับไฟล์ (จาวาสคริปต์บน server
ยอมให้คุณเข้าถึงไฟล์ได้) ถ้ามีข้อผิดพลาดเกิดขึ้นตอนเปิดไฟล์ บล็อก finally
สามารถปิดไฟล์ได้ก่อนที่สคริปต์จะทำงานผิดพลาด
openMyFile(); try { writeMyFile(theData); //This may throw a error }catch(e){ handleError(e); // If we got a error we handle it }finally { closeMyFile(); // always close the resource }
ถ้าบล็อก finally
คืนค่ากลับมา, ค่านี้จะกลายเป็นผลลัพธ์จาก try-catch-finally
โดยไม่สนใจว่าคำสั่ง return
ในบล็อก try
และ catch
จะคืนค่าอะไร
function f() { try { alert(0); throw "bogus"; } catch(e) { alert(1); return true; // this return statement is suspended until finally block has completed alert(2); // not reachable } finally { alert(3); return false; // overwrites the previous "return" alert(4); // not reachable } // "return false" is executed now alert(5); // not reachable } f(); // alerts 0, 1, 3; returns false
การซ้อนกันของคำสั่ง try...catch
คุณอาจซ้อนคำสั่ง try...catch
เข้าด้วยกันได้ ถ้าคำสั่ง try...catch
ชั้นใน ไม่มีบล็อก catch
, บล็อก catch
ของคำสั่ง try...catch
ข้างนอก จะตรวจหาข้อผิดพลาดแทน
การใช้งานอ็อบเจกต์ข้อผิดพลาด
ด้วยชนิดของข้อผิดพลาด, คุณอาจจะใช้คุณสมบัติ 'name' และ 'message' เพื่อให้ได้ข้อความที่สมบูรณ์ขึ้น โดยทั่วไป 'name' จะใช้ระบุชนิดของข้อผิดพลาด (เช่น 'DOMException' หรือ 'Error') และ 'message' จะใช้แสดงข้อความย่อ ที่สั้นกว่าการแปลงอ็อบเจกต์ข้อผิดพลาดให้เป็นสตริง
ถ้าคุณสร้างอ็อบเจกต์ข้อผิดพลาดเอง และต้องการใช้ประโยชน์จากคุณสมบัติต่างๆเหล่านี้ (เช่น บล็อก catch ของคุณไม่แยกแยะระหว่างข้อผิดพลาดของคุณเองกับของระบบ) คุณสามารถใช้ตัวสร้างอ็อบเจกต์ชนิด Error ได้ ดังตัวอย่าง:
function doSomethingErrorProne () { if (ourCodeMakesAMistake()) { throw (new Error('The message')); } else { doSomethingToGetAJavascriptError(); } } .... try { doSomethingErrorProne(); } catch (e) { alert(e.name);// alerts 'Error' alert(e.message); // alerts 'The message' or a JavaScript error message) }