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.