Why is this an issue?

In JavaScript, labels are identifiers that allow you to name blocks of code, such as loops and conditional statements. They are used in conjunction with statements like break and continue to control the flow of execution within nested loops and conditionals.

It’s worth noting that labels are not widely used in modern JavaScript programming because they can lead to complex and hard-to-maintain code. In most cases, there are better alternatives to achieve the desired control flow without resorting to labels.

myLabel: {
  let x = doSomething();
  if (x > 0) {
    break myLabel;
  }
  doSomethingElse();
}

If you find yourself using labels, you should reevaluate your code structure and explore other options for better code clarity and maintainability.

let x = doSomething();
if (x <= 0) {
  doSomethingElse();
}

Exceptions

Labels placed on loops and used exclusively for multi-level loop exits (where break or continue targets the label from within a nested inner loop) are not flagged. This pattern is an accepted way to exit multiple loop levels without requiring flag variables or significant restructuring.

outer: for (const tag of newTags) {
  for (const existing of existingTags) {
    if (existing.id === tag.id) continue outer; // Compliant: multi-level loop exit
  }
  result.push(tag);
}

Similarly, no issue is raised for labeled loop statements when all break references to the label originate from within a nested switch. Inside a switch, a plain break only exits the switch itself, making break label the only valid mechanism to exit the enclosing loop from within a switch case.

scan: while (pos < text.length) {
  switch (text.charCodeAt(pos)) {
    case 10:
      if (condition) {
        break scan; // Compliant: 'break' would only exit the switch; label is needed to exit the loop
      }
      break;
  }
  pos++;
}

Resources

Documentation