这段代码计算了什么?

时间:2014-11-20 14:24:56

标签: javascript

面试问题,

此代码计算了什么?

    (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.

2 个答案:

答案 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

然后,如果你分析代码:

  • 如果输入为0,则函数返回1.
  • 如果输入大于0,则返回输入乘以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!