ตั้งแต่ JavaScript 1.2 Label สามารถใช้กับ break เพื่อ ระบุลูปชั้นนอกที่ต้องการออกจาก ได้ แทนที่จะออกจากแค่ลูปชั้นในสุด
ตัวอย่างโค้ด
<html>
<body>
<script>
document.write("Entering the loop!<br />");
outerloop: // Label Name
for (var i = 0; i < 5; i++) {
document.write("Outerloop: " + i + "<br />");
innerloop:
for (var j = 0; j < 5; j++) {
if (j > 3) break; // ออกจาก innerloop
if (i == 2) break innerloop; // ออกจาก innerloop (Explicit)
if (i == 4) break outerloop; // ออกจาก outerloop!
document.write("Innerloop: " + j + " <br />");
}
}
document.write("Exiting the loop!<br />");
</script>
</body>
</html>
การวิเคราะห์ Flow
i=0,1: Innerloop วน j=0..3 (break เมื่อ j>3) → พิมพ์ 0,1,2,3i=2:break innerloop→ Innerloop หยุดทันที ไปi=3i=3: Innerloop วน j=0..3 ปกติi=4:break outerloop→ ออกจาก Outerloop ทั้งหมด จบลูป
ผลลัพธ์ที่คาดหวัง
Entering the loop! Outerloop: 0 Innerloop: 0 Innerloop: 1 Innerloop: 2 Innerloop: 3 Outerloop: 1 Innerloop: 0 Innerloop: 1 Innerloop: 2 Innerloop: 3 Outerloop: 2 Outerloop: 3 Innerloop: 0 Innerloop: 1 Innerloop: 2 Innerloop: 3 Outerloop: 4 Exiting the loop!
Label กับ Block Statement (ไม่ใช่ Loop)
Label สามารถใช้กับ Block { } ได้ แต่ break เท่านั้น (continue ไม่ได้):
myBlock: {
console.log("1");
if (condition) break myBlock; // ออกจาก Block
console.log("2"); // ไม่รันถ้า break
}
console.log("3"); // รันต่อ
ข้อจำกัด
- Label ต้องอยู่ ทันทีก่อน Loop/Block ที่ต้องการ Label
break labelใช้ได้กับ Loop และ Block |continue labelใช้ได้กับ Loop เท่านั้น- Label Scope = Function Scope
- ไม่สามารถกระโดดข้าม Function Boundary (ไม่ใช่ Goto)
แนวทางปฏิบัติที่ดี
- ใช้ Label เฉพาะเมื่อจำเป็นจริง (Nested Loop ซับซ้อนมาก)
- ตั้งชื่อ Label ให้สื่อความหมาย:
outerLoop:,searchLoop:,retryBlock: - เพิ่ม Comment อธิบายจุดประสงค์
- พิจารณา Refactor: แยก Function, ใช้ Return, Flag Variable, หรือ Array Methods
ตัวเลือกแทน Label (แนะนำ)
// แทน break outerloop
function findInMatrix(matrix, target) {
for (const row of matrix) {
for (const cell of row) {
if (cell === target) return { row, cell }; // Early Return
}
}
return null;
}
// แทน continue outerloop
function processRows(rows) {
for (const row of rows) {
if (shouldSkipRow(row)) continue; // Row-level continue
for (const cell of row) {
processCell(cell);
}
}
}