Arguments.callee - 阶乘模式

Arguments.callee - Factorial Pattern

假设:

var x = { 
  y: function(n){ 
    console.log(n);
    console.log(n+":"+( n > 0 ? arguments.callee(n-1) + "o" : "all" ));
  } 
}; 
x.y(4)

控制台日志:

4 
3 
2 
1 
0 
0 -> all
1 -> o
2 -> o
3 -> o
4 -> o

console.log 的第一部分对我来说很有意义,我们从 n=4 开始,然后用 n-1 调用函数本身,结果是 4,3,2,1,0 .

但是,

的输出
console.log(n+":"+( n > 0 ? arguments.callee(n-1) + "o" : "all" ));

有点烦人,因为它 returns 结果是 'reversed' 顺序。 为什么 n 的值作为该执行的第一部分,其中没有 arguments.callee 给出的结果与从带有 arguments.callee 的三元运算符中调用它的结果不同? 这是一个纯粹的定义问题还是有其他逻辑原因?

The process would be as the following:
(n=4) = ( 4 > 0 ? arguments.callee(3) + "o" : "all" ) = "o"
  (n=3) = ( 3 > 0 ? arguments.callee(2) + "o" : "all" ) = "o"
    (n=2) = ( 2 > 0 ? arguments.callee(1) + "o" : "all" ) = "o"
      (n=1) = ( 1 > 0 ? arguments.callee(1) + "o" : "all" ) = "o"
        (n=0) = ( 0 > 0 ? arguments.callee(1) + "o" : "all" ) = "all"

这不是必须以 ooooall 而不是 alloooo 结束吗?

干杯

当您在表达式中间进行递归调用时,该调用必须执行到完成。递归调用中发生了什么? console.log() 的另一个迭代,就是这样。因此,在第一个(对应于 4)调用完成之前,3210 的调用必须先完成。

此外,没有理由使用 arguments.callee。只需给您的匿名函数一个内部名称:

var x = { 
  y: function y(n){ 
    console.log(n);
    console.log(n+":"+( n > 0 ? y(n-1) + "o" : "all" ));
  } 
}; 

假设您不是 2008 年的时间旅行者,y 名称仅绑定 函数中。

不,因为是一个递归函数所以,当最后一个函数结束时("all")然后所有之前的console.log将以相反的顺序打印(真的不是相反的顺序,这是正确的顺序因为是一个递归函数),例如,我们有你说的 5 个步骤:(n=4, n=3 ... n=0):

f4 -> f3 -> f2 -> f1 -> f0

我们看到 f4 调用了 f3,f3 调用了 f2 ..... 而 f1 调用了 f0。好吧,当 f0 完成时,console.log 输出“0”和 "all",然后,这个函数 (f0) return 到打印字母 [=20 的前一个函数 (f1) =], 然后 f1 return 到 f2 ...... 以同样的方式直到 return 到第一个函数 f4.

说起来难,易懂。我希望我的 "explanation" 足够了。