views:

37

answers:

1

Alright, to start with let's look at some code:

<html>
    <body>
        <script type="text/javascript">
            function logFunction(fn) {
                console.log(fn.prototype);
                console.log(fn);
                console.log(fn(4));
            }
            var num = 5;
            var add5 = function(x) { return x + 5 };
            var addNum = function(x) { return x + num };
            var adder = function(y) { return function(x) { return x + y } };
            logFunction(add5);
            logFunction(addNum);
            logFunction(adder(5));
        </script>
    </body>
</html>

When executed, it returns the following results:

Object
    constructor: function (x) { return x + 5 }
    __proto__: Object
function (x) { return x + 5 }
9

Object
    constructor: function (x) { return x + num }
    __proto__: Object
function (x) { return x + num }
9

Object
    constructor: function (x) { return x + y }
    __proto__: Object
function (x) { return x + y }
9

While it would be very easy in the first case to see that the value that x will be added to is 5, I cannot seem to come up with a way to do the same with the other two cases.

My question is this: Is there a way to determine the value of what x is being added to in the last two examples, armed only with the function reference and the knowledge of what the variable is called ("num", "y" etc.)?

EDIT:

Alright, I can see that finding these values is indeed impossible. The only way would be if I could have access to the anonymous function's 'arguments' property, but alas, that too is impossible. My work around for this is to require an Object of type Function as a parameter. There are still some problems with this, as can be seen in my new code below, but this should work for my case. Thanks everyone!

<html>
    <body>
        <script type="text/javascript">
            function logFunction(fn) {
                console.log(fn.prototype);
                console.log(fn);
                console.log(fn(4));
                console.log("");
                console.log("");
            }
            var num = 5;
            var addNumFunc = new Function("x", "return x + " + num);
            var whereNumFunc = new Function("x", "return x >= " + num * num);
            var adderFunc = new Function("y", "return function(x) { return x + y }");
            var adderFuncFunc = new Function("y", "return new Function(\"x\", \"return x + \" + y)");
            logFunction(addNumFunc);
            logFunction(whereNumFunc);
            logFunction(adderFunc);
            logFunction(adderFunc(5));
            logFunction(adderFuncFunc);
            logFunction(adderFuncFunc(5));
        </script>
    </body>
</html>

Which returns:

anonymous
function anonymous(x) {
return x + 5
}
9

anonymous
function anonymous(x) {
return x >= 25
}
false

anonymous
function anonymous(y) {
return function(x) { return x + y }
}
function (x) { return x + y }

Object
function (x) { return x + y }
9

anonymous
function anonymous(y) {
return new Function("x", "return x + " + y)
}
function anonymous(x) {
return x + 4
}

anonymous
function anonymous(x) {
return x + 5
}
A: 

In the case of num:

num is a global property. If you have that knowledge (that it is a global property), then you know that you can access it like so:

window.num

In the case of y:

y is a property that is in the scope chain of the function that was created by executing adder(5). That function has access to the value of y, but the code outside of that function does not have access to it.

var closureFunction = adder(5);

The function closureFunction has the y property in its scope chain, and if you run this function, the value of y will be added to the passed-in argument. However, if you refactor your code you could enable the retrieval of the value of y.

Your code:

var adder = function(y) {
    return function(x) { 
        return x + y;
    };
};

Refactored code:

var adder = function(y) {
    var fn = function(x) { 
        return x + y;
    };
    fn.getArgument = function() { return y; };
    return fn;
};

Now you can get y like so:

closureFunction.getArgument();

This should be thought trough.

Šime Vidas
Thank you for your answer!
diceguyd30