简体   繁体   中英

Javascript: About Return()() format tail recursion in Fibonacci function

function fibonacci(n) {
    return (function(a, b, i) {
        return (i < n) ? arguments.callee(b, a + b, i + 1) : a;
    })(1, 1, 1);
}

Hey, I am a rookie, I could understand the math logical part of this function, what I did not understand is the parameter passing progress, it passes (1,1,1) to the function(abi), which seems not very normal.

function fibonacci(n) {
    return (function(a, b, i) {
        return (i < n) ? arguments.callee(b, a + b, i + 1) : a;
    })
    regular function pass a parameter like the way function(1 1 1)
}

I can not understand this, I tried to abstract it into finally the

function fibonacci(n){
    return()()
}

format, but how could this pass the parameter, I guess it is something about the return call could not handle a function call after it which also works in it.

So, is there some basic stuff I havent learnt? Like some default format like the entries in MDN?

Thnx a lot.

 return (function(a, b, i) { return (i < n) ? arguments.callee(b, a + b, i + 1) : a; })(1, 1, 1); 

is an anonymous function expression that is immediately invoked. The parenthesis around it are not required .

The usage of arguments.callee is deprecated, this would better have been written with a named function expression:

return (function recurse(a, b, i) {
    return (i < n) ? recurse(b, a + b, i + 1) : a;
})(1, 1, 1);

which is equivalent to the function declaration and invocation

function recurse(a, b, i) {
    return (i < n) ? recurse(b, a + b, i + 1) : a;
}
return recurse(1, 1, 1);

Your final abstraction is wrong. It's not return()() but it is:

return      ( function(){} )()

Note that the () does not belong to return since return is not a function. In this case, () act as grouping parenthesis. In the same way when you use it like:

return (1+1)*2

Here, adding *2 behind the () works because the parenthesis is not part of a function invocation but is instead used as a grouping operator. Or more precisely, an expression evaluator.

You see, how (1+1)*2 works is that the () is recognized as not being part of a function call, thus it's contents are treated as an expression. So it is parsed as:

temporary_variable = 1+1;
temporary_variable * 2;

In the same way, (function(){})() is parsed as:

temporary_variable = function(){};
temporary_variable();

Thus, the whole thing is basically doing this:

function f (n) {
    temporary_variable = function (a,b,i) {
        /* ... */
    }
    return temporary_variable(1,1,1);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM