Reputation: 67
The last example of http://javascriptissexy.com/understand-javascript-closures-with-ease/ is:
function celebrityIDCreator (theCelebrities) {
var i;
var uniqueID = 100;
for (i = 0; i < theCelebrities.length; i++) {
theCelebrities[i]["id"] = function (j) { // the j parametric variable is the i passed in on invocation of this IIFE
return function () {
return uniqueID + j; // each iteration of the for loop passes the current value of i into this IIFE and it saves the correct value to the array
} () // BY adding () at the end of this function, we are executing it immediately and returning just the value of uniqueID + j, instead of returning a function.
} (i); // immediately invoke the function passing the i variable as a parameter
}
return theCelebrities;
};
var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}];
var createIdForActionCelebs = celebrityIDCreator (actionCelebs);
var stalloneID = createIdForActionCelebs[0];
console.log(stalloneID.id); // 100
console.log(createIdForActionCelebs[1].id); // 101
I don't understand why IIFE is needed here, I replaced celebrityIDCreator
with and produced the same results:
var celebrityIDCreator = function(theCelebrities) {
var i;
var uniqueID = 100;
for (i = 0; i < theCelebrities.length; i++) {
theCelebrities[i]["id"] = function (j) {
return uniqueID + j;
// return function () {
// } () ;
} (i);
}
return theCelebrities;
};
Could some one explains this? Do I miss anything?
Upvotes: 1
Views: 83
Reputation: 6112
I think it is a mistake on the blog. If you see the Closures Gone Awry section's first example, id
is created as a function. But, in the second example, which you are referring to and which aims to solve a bug in the first, id
is created as a property.
I think the second example should be like this in order to make it similar to the first. Notice the NOTEs in the code, near the IIFE in question and the consumption of id
as a function
function celebrityIDCreator(theCelebrities) {
var i;
var uniqueID = 100;
for (i = 0; i < theCelebrities.length; i++) {
theCelebrities[i]["id"] = function(j) { // the j parametric variable is the i passed in on invocation of this IIFE
return function() {
return uniqueID + j; // each iteration of the for loop passes the current value of i into this IIFE and it saves the correct value to the array
} // NOTE. Not an IIFE
}(i); // immediately invoke the function passing the i variable as a parameter
}
return theCelebrities;
};
var actionCelebs = [{
name: "Stallone",
id: 0
}, {
name: "Cruise",
id: 0
}, {
name: "Willis",
id: 0
}];
var createIdForActionCelebs = celebrityIDCreator(actionCelebs);
var stalloneID = createIdForActionCelebs[0];
console.log(stalloneID.id()); // 100 NOTE: Use as function
console.log(createIdForActionCelebs[1].id()); // 101 NOTE: Use as function
Apart from this, I believe you're not missing anything. Your code is right, if id
needs to be a property.
Upvotes: 1