4

While developer a client side application I ran into an error that I believe is related to my incomplete understanding of use of closures. I have trimmed down my code to the following :


var fn1 = function(arr){ 
  return function(val){ 
    var idx;
    var x = 20; 
    for (idx in arr) {
      arr[idx]();
    } 
  } 
}

var fn2 = fn1([function(){
  x+= 20; 
  alert(x);
}])

Now upon executing :

fn2()

I receive an error : ReferenceError: reference to undefined property "x"

I would like to know why this error is arising and why can't fn2 access the variables defined in the local scope of closure function returned by fn1 ?

2 Answers 2

8

In short: closures have access to parent scopes in relation to where they were declared, not where they are used.

The function returned by fn1 has access to the scope of its parent function (fn1 itself), i.e., it has access to arr. But the functions inside your array do not have access to variables defined within fn1 or within the function returned from it, because those functions (inside array) were declared in a different scope.

Regarding the actual problem you're trying to solve with that code, I'm not sure if I understood it correctly. Looks like you're trying to apply some functions to a certain number. I don't understand why that number (20 in your example) is a constant and not a parameter. Here is my proposed solution for that (no closures!):

var applyArrayFunctions = function(arr, x){ 
    for(var i=0; i<arr.length; i++) {
        x = arr[i](x);
    }
    return x;
}

var num = 2;
var fnArray = [
    function(val){
      return val + 20; 
    },
    function(val){
      return val * 2; 
    }
];

console.log(applyArrayFunctions(fnArray, num));​ // logs 44​​​
Sign up to request clarification or add additional context in comments.

11 Comments

Also explanation needed not to use fon-in for arrays and solution to actual question code-wise would be better.
Thanks for the carification. Very clearly stated. Removed my misconception.
@Sarfraz I simply removed the hasOwnProperty check for making the code consize. Thanks for the tip though.
@Lorefnon: No i mean you should NOT use for-in loop for arrays (it is used for objects), use simple for loop eg for (idx = 0; idx < arr.length; idx++) {...}
@Lorefnon: Simple: Use for-in only for objects not arrays. If you have confusion about the difference between an object and array, you can ask a question to get help on that too.
|
3

I suspect the error is in the line x+=20

var x = 20 only exists inside the scope of the anonymous function returned by fn1. x+=20 evaluates before fn1 does, so x doesn't even exist at that time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.