1

As you can see in the example below, I'm trying to wrap every function defined in obj so it gets to be able to be called with anotherObj as this, and then add that wrapper as a property to anotherObj.

Note: isFunction

var isFunction = function(x) {
    return typeof(x) == "function";
}
for (prop in obj) {
    if (isFunction(obj[prop])) {
        var fn = obj[prop];
        anotherObj[prop] = function() {
            fn.call(anotherObj);
        };
    }
}

For some reason weird to me, every property now stored in anotherObj, references only the last property of the iteration.

However, if I use an external function like below, the references are ok.

var contextFn = function(fn, context){
    return function() {
        fn.call(context);
    };
};
...
for (prop in obj) {
    ...
        anotherObj[prop] = contextFn(fn, anotherObj);
    ...
}

Why is this happening? Is there something obvious I'm missing?

Guido Tarsia
  • 1,962
  • 4
  • 27
  • 45
  • possible duplicate of [How do I pass the value (not the reference) of a JS variable to a function?](http://stackoverflow.com/questions/2568966/how-do-i-pass-the-value-not-the-reference-of-a-js-variable-to-a-function) – DCoder May 01 '14 at 20:09
  • 1
    There are hundreds of similar questions here, but their similarity is unfortunately not obvious until you've "gotten" the basic behavior. – Pointy May 01 '14 at 20:09
  • Yeah... I do need some Javascript in-depth reading, do you have any recommendations? – Guido Tarsia May 01 '14 at 20:12

1 Answers1

2

The (not-so-)obvious thing you're missing is that in your first loop, the variable "fn" is not local to the statement block it's declared in. Thus, it's shared by all the functions you're creating.

Your solution is in fact the correct one. By using a separate function, you're making copies of the values to be used in creating the actual wrapper functions, so that each wrapper will have it's own private copy of "fn".

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    This is correct and is why JSLint suggests that you "do not make functions in a loop". You could start by googling this. To be clear the reason it is "shared by all the functions" is because the closure created when you define each new function refers to the actual live (and changing) value of "fn" – Woody May 01 '14 at 20:15