0

I am trying to grasp the concept of closure in javascript and come across the following codes on http://javascriptissexy.com:

// This example is explained in detail below (just after this code box).​
function celebrityIDCreator (theCelebrities) {
var i;
var uniqueID = 100;
for (i = 0; i < theCelebrities.length; i++) {
  theCelebrities[i]["id"] = function ()  {
    return uniqueID + i;
  }
 }

 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());//103

In the preceding example, by the time the anonymous functions are called, the value of i is 3 (the length of the array and then it increments). The number 3 was added to the uniqueID to create 103 for ALL the celebritiesID. So every position in the returned array get id = 103, instead of the intended 100, 101, 102.

Question: Can anyone explain to me why the value of stallonID is 103 instead of 100? I am lost at "The number 3 was added to the uniqueID to create 103 for ALL the celebritiesID.".

Thanks!

  • @charlietfl perhaps you could add a link to the existing question to aid the questioner – korwalskiy Nov 14 '17 at 03:07
  • @korwalskiy the link is very clearly oulined at top of the question – charlietfl Nov 14 '17 at 03:09
  • function celebrityIDCreator (theCelebrities) { var i; var uniqueID = 100; for (i = 0; i < theCelebrities.length; i++) { theCelebrities[i]["id"] = (function (id) { return function () { return id ; } })(uniqueID+i) } console.log(theCelebrities) 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());//103 – Sabha B Nov 14 '17 at 03:20
  • TL/DR; the answers in the reference duplicate question -- closure is a concept that allows properties in a parent code can be referenced by a child execution context created by the parent even after the parent execution content has ended -- in your question, "id" holds a function expression not an integer, therefore at time of calling the function expression its reference to the variable "i" will the last value of "i" as set by the for loop in the parent scope – korwalskiy Nov 14 '17 at 04:05

1 Answers1

0

As you see here actionCelebs array every object element id refers to the closure function, which has not been run yet, untill you access the actionCelebs[1]['id'] like this,

when that closure get run, you know closer has access to outer function variable by reference that means if inside a closure a referenced outer function variable changes,it changes in the outer function too.

In your codecelebrityIDCreator() runs the for loop, i from 0 - 3, and your closure function not getting executed,

so after the celebrityIDCreator() finishes, inside the celebrityIDCreator() scope the value i = 3,

so when you finally acces createIdForActionCelebs[0]['id'] the closure function gets run and in this line return uniqueID + i finds i's value 3 everytime from outer function scope, that's why your id is always 103 enter image description here

shahin mahmud
  • 945
  • 4
  • 11
  • if somehow you are confused about the loop, because (i = 0, i < 3, i++), when i = 2 and i < 3 then it enters into the loop, so i increments to 3, in the next round 3<3 false, loop terminates, but i's value is 3 finally – shahin mahmud Nov 14 '17 at 04:35