简体   繁体   中英

Confusion regarding javascript closure

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 ?

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), ie, 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​​​

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.

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