面试问题,
此代码计算了什么?
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(10);
a) 10!
b) Nothing, it's an infinite loop.
c) 10 to the power of 10
d) 10!/10
e) The 10th Fibonacci number.
答案 0 :(得分:2)
a) 10!
意味着阶乘10(数学表达式为10 x 9 x 8 x ... x 1)
您可以通过连续调用猜测结果:
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(1);
1
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(2);
2
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(3);
6
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(4);
24
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(5);
120
(function(n){return (n && n*arguments.callee(n-1)) || 1;})(10);
3628800
然后,如果你分析代码:
n-1
调用的函数。更确切地说,(n && n*arguments.callee(n-1))
是一个布尔运算,它的返回值是最后一个被评估为true的操作数,每次n*arguments.callee(n-1)
都是n>0
的值,而是{1}(感谢到||1
)。
arguments.callee
是javascript中的递归调用。
答案 1 :(得分:1)
分析递归调用的一种简单方法是记下所有调用的堆栈,然后按弹出顺序进行评估。
[
10 * (recurse with 10 - 1),
9 * (recurse with 9 - 1),
8 * (recurse with 8 - 1),
7 * (recurse with 7 - 1),
6 * (recurse with 6 - 1),
5 * (recurse with 5 - 1),
4 * (recurse with 4 - 1),
3 * (recurse with 3 - 1),
2 * (recurse with 2 - 1),
1 * (recurse with 1 - 1),
1 (recursion stops because 0 is falsey, therefore 1 will be returned)
]
然后我们采取堆栈并评估我们的方式:
[
10 * 362880 = 3628800,
...,
6 * 120 = 720,
5 * 24 = 120,
4 * 6 = 24,
3 * 2 = 6,
2 * 1 = 2,
1 * 1 = 1
1 = 1 <-- start here then work up
]
由此,我们可以清楚地看到算法是a) 10!
。