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
)调用完成之前,3
、2
、1
和 0
的调用必须先完成。
此外,没有理由使用 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" 足够了。
假设:
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
)调用完成之前,3
、2
、1
和 0
的调用必须先完成。
此外,没有理由使用 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" 足够了。