Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
484 views
in Technique[技术] by (71.8m points)

javascript - Puzzle: JS Function that returns itself until there are no arguments

I'm trying to solve a puzzle, and am at my wit's end trying to figure it out.

I'm supposed to make a function that works like this:

add(1);       //returns 1
add(1)(1);    //returns 2
add(1)(1)(1); //returns 3

I know it can be done because other people have successfully completed the puzzle. I have tried several different ways to do it. This is my most recent attempt:

function add(n) {
    //Return new add(n) on first call
    if (!(this instanceof add)) {
        return new add(n);   
    }

    //Define calc function
    var obj = this;
    obj.calc = function(n) {
        if (typeof n != "undefined") {
            obj.sum += n;
            return obj.calc;            
        }

        return obj.sum;
    }

    //Constructor initializes sum and returns calc(n)
    obj.sum = 0;
    return obj.calc(n);
}

The idea is that on the first call, a new add(n) is initialized and calc(n) is run. If calc receives a parameter, it adds n to sum and returns itself. When it eventually doesn't receive a parameter, it returns the value of sum.

It makes sense in theory, but I can't get it to work. Any ideas?

--edit--

My code is just the route I chose to go. I'm not opposed to a different approach if anyone can think of one.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To answer "how dow this work". Given:

function add(n) {
    function calc(x) {
        return add(n + x);
    }
    calc.valueOf = function() {
        return n;   
    }
    return calc;
}

var sum = add(1)(2)(3); // 6

When add is called the first time, it stores the value passed in in a variable called n. It then returns the function calc, which has a closure to n and a special valueOf method (explained later).

This function is then called with a value of 2, so it calls add with the sum of n + x, wich is 1 + 2 which 3.

So a new version of calc is returned, this time with a closure to n with a value of 3.

This new calc is called with a value of 3, so it calls add with n + x, which this time is 3 + 3 which is 6

Again add returns a new calc with n set to 6. This last time, calc isn't called again. The returned value is assigned to the variable sum. All of the calc functions have a special valueOf method that replaces the standard one provided by Object.prototype. Normally valueOf would just return the function object, but in this case it will return the value of n.

Now sum can be used in expressions, and if its valueOf method is called it will return 6 (i.e. the value of n held in a closure).

This seems pretty cool, and sum will act a lot like a primitve number, but it's actually a function:

typeof sum == 'function';

So be careful with being strict about testing the type of things:

sum * 2   // 12
sum == 6  // true

sum === 6 // false -- oops!!

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...