Javascript BabelJS如何实现尾部递归?
Babel如何实现尾部递归Javascript BabelJS如何实现尾部递归?,javascript,tail-recursion,babeljs,Javascript,Tail Recursion,Babeljs,Babel如何实现尾部递归 这是怎么回事?认为我会发布一个详细的解释,让那些从谷歌登陆这里的人能够更快地理解 请注意,以下解释是根据我从代码中可以看出的内容得出的(没有咨询Babel的作者或代码中的其他专家),因此不知道我得出的含义是否是@sebmck或其他促成此转换的人的预期含义 "use strict"; // ES2015/ES6 modules are assumed to be in strict mode. function factorial(_x2) { // This
这是怎么回事?认为我会发布一个详细的解释,让那些从谷歌登陆这里的人能够更快地理解 请注意,以下解释是根据我从代码中可以看出的内容得出的(没有咨询Babel的作者或代码中的其他专家),因此不知道我得出的含义是否是@sebmck或其他促成此转换的人的预期含义
"use strict"; // ES2015/ES6 modules are assumed to be in strict mode.
function factorial(_x2) {
// This variable is the list of arguments to factorial.
// Since factorial may be called again from within this function
// (but must be called indirectly to prevent call stack growth),
// a custom arguments-like variable must be maintained.
var _arguments = arguments;
// _again equals true when the original factorial function should be called
// once more.
var _again = true;
// This line creates a labeled while loop, use to allow continuing this
// specific loop, without the requirement of having no nested while loops
// Nested while loops would cause a "continue" statement within them to
// execute them, not this loop.
_function: while (_again) {
// The variable used in the original factorial function was called "n",
// this method allows Babel to not rename it, but simply assign the
// possibly modified first argument of the factorial function to it.
var n = _x2;
// Temporal dead zone (TDZ) mechanic
acc = undefined;
// The "use strict" directive from the original function
"use strict";
// Beginning of user code, this is always inserted to ensure that if
// this is the final run, the while loop will not run again.
_again = false;
// This is Babel's default argument handling. The steps, in order, are:
// 1. Make sure that there will not be an out-of-bounds access for the
// undefined check.
// 2. Check if the second argument to the current iteration is undefined,
// if yes: the default value is `1`, if no, use the value of the first argument.
var acc = _arguments.length <= 1 || _arguments[1] === undefined ? 1 : _arguments[1];
// Input code - no modifications.
if (n <= 1) return acc;
// The following three lines are the call to factorial() within factorial
// in the input code. The first line assigns the new arguments, as well
// as updating the _x2 variable to it's new value. The second line
// overrides the assignment in the beginning of the loop.
// The third line brings the loop back to the beginning.
_arguments = [_x2 = n - 1, n * acc];
_again = true;
continue _function;
}
}
“严格使用”//假设ES2015/ES6模块处于严格模式。
函数阶乘(x2){
//此变量是阶乘的参数列表。
//因为阶乘可以从这个函数中再次调用
//(但必须间接调用以防止调用堆栈增长),
//必须维护像变量这样的自定义参数。
变量_参数=参数;
//_在调用原始阶乘函数时再次等于true
//再一次。
var _再次=真;
//此行创建一个带标签的while循环,用于允许继续此操作
//特定循环,无需嵌套while循环
//嵌套的while循环会导致其中的“continue”语句
//执行它们,而不是这个循环。
_函数:while(请再说一遍){
//原始阶乘函数中使用的变量称为“n”,
//此方法允许Babel不重命名它,而只指定
//可能修改了阶乘函数的第一个参数。
var n=_x2;
//时间死区(TDZ)机制
acc=未定义;
//原始函数中的“use strict”指令
“严格使用”;
//在用户代码的开头,始终插入此项,以确保
//这是最后一次运行,while循环将不再运行。
_再次=假;
//这是Babel的默认参数处理。按顺序,步骤如下:
//1.确保不会有对服务器的越界访问
//未定义的检查。
//2.检查当前迭代的第二个参数是否未定义,
//如果是:默认值为“1”,如果不是,则使用第一个参数的值。
var acc=_arguments.length这可能不是SO的问题,但每个递归调用都可以重写为迭代循环(反之亦然).Babel没有做任何特殊的事情。谢谢@Lapixx。我理解递归调用与迭代循环部分,我没有得到尾部部分,但我想我现在得到了,它是一个标签,它不是做函数调用,而是在函数标签处执行继续。