0
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.

I read the callback function article and when i cannot get to this sentence, I mean how to explain we alway get id=103?
I have searched the web but cannot find a good answer. Hope here i can get over it. thanks.

Frank Lee
  • 161
  • 10
  • I am a newbie here in javascript. Please explain me the easiest way. Many Thanks^_^ – Frank Lee Dec 06 '15 at 13:45
  • I kind of know the reason:the closure (the anonymous function in this example) has access to the outer function’s variables by reference, not by value. but I still don't understand why get id=103 thing. Do i miss something? Thanks – Frank Lee Dec 06 '15 at 13:48
  • 1
    Yes, it has to do with closures. In `celebrityIDCreator`, you're storing functions and all of these functions will use the last value of `i`. You have to capture i to have a unique ID for each star. More details here: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1 – Shanoor Dec 06 '15 at 13:56

2 Answers2

1

The reason for this is that you are using a callback function. Callbacks are supposed to be executed once called. Thus, it will be performed once you actually call it.

In your case, the return of your callback on each iteration is always the last value of i + uniqueID.

Aldee
  • 4,439
  • 10
  • 48
  • 71
1

It is because of closure. Read about it here and here.

This should solve your problem:

function celebrityIDCreator(theCelebrities) {
    var i;
    var uniqueID = 100;
    for (i = 0; i < theCelebrities.length; i++) {
        theCelebrities[i]["id"] = (function (index) {
            return function () {
                return uniqueID + index;
            };
        })(i);
    }

    return theCelebrities;
};
Community
  • 1
  • 1
Kunal Kapadia
  • 3,223
  • 2
  • 28
  • 36