Babel.js 尾调用中的“_function: while”语法是什么?

What's this "_function: while" syntax in Babel.js tail call?

最近我在看Babel.js (previously 6to5)。它是 ES6 的转译器。它提供的一个有趣的功能是将尾部调用更改为循环。在示例中:

function factorial(n, acc = 1) {
    "use strict";
    if (n <= 1) return acc;
    return factorial(n - 1, n * acc);
}

// Stack overflow in most implementations today,
// but safe on arbitrary inputs in eS6
factorial(100000)

Babel.js 将其转译为:

"use strict";

var _temporalAssertDefined = function (val, name, undef) { if (val === undef) { throw new ReferenceError(name + " is not defined - temporal dead zone"); } return true; };

var _temporalUndefined = {};
function factorial(_x2) {
    var _arguments = arguments;
    var _again = true;

    _function: while (_again) {
        var n = _temporalUndefined;
        var acc = _temporalUndefined;
        _again = false;
        var n = _x2;
        n = acc = undefined;
        n = _arguments[0] === undefined ? undefined : _arguments[0];
        acc = _arguments[1] === undefined ? 1 : _arguments[1];

        "use strict";
        if ((_temporalAssertDefined(n, "n", _temporalUndefined) && n) <= 1) {
            return _temporalAssertDefined(acc, "acc", _temporalUndefined) && acc;
        }_arguments = [_x2 = (_temporalAssertDefined(n, "n", _temporalUndefined) && n) - 1, (_temporalAssertDefined(n, "n", _temporalUndefined) && n) * (_temporalAssertDefined(acc, "acc", _temporalUndefined) && acc)];
        _again = true;
        continue _function;
    }
}

// Stack overflow in most implementations today,
// but safe on arbitrary inputs in eS6
factorial(100000);

我的问题是,我从未见过像 _function: while(again) 这样的 JavaScript 语法。但它是有效的JavaScript!我尝试在 Chrome devtools 控制台中输入类似 a: 1 的代码,它是正确的。

谁能告诉我:

  1. 这个语法的名称是什么?
  2. 从哪里可以获得语法信息?
  3. 在什么情况下我们需要这样写代码?

它是一个标签,与 continue、break 一起使用:

my_label: while(true) {
  while(true) {
    break my_label;
  }
}
console.log('did we survive?');

Avoid using labels

Labels are not very commonly used in JavaScript since they make programs harder to read and understand. As much as possible, avoid using labels and, depending on the cases, prefer calling functions or throwing an error.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label