JavaScript closure and variable scope

I am having problems closing JS:

// arg: an array of strings. each string is a mentioned user.
// fills in the list of mentioned users. Click on a mentioned user name causes the page to load that user info.
function fillInMentioned(mentions) {
    var mentionList = document.getElementById("mention-list");
    mentionList.innerHTML = "";
    for (var i = 0; i < mentions.length; i++) {
        var newAnchor = document.createElement("a");

        // cause the page to load info for this screen name
        newAnchor.onclick = function () { loadUsernameInfo(mentions[i]) };

        // give this anchor the necessary content
        newAnchor.innerHTML = mentions[i];

        var newListItem = document.createElement("li");
        newListItem.appendChild(newAnchor);
        mentionList.appendChild(newListItem);
    }
    document.getElementById("mentions").setAttribute("class", ""); // unhide. hacky hack hack.
}

Unfortunately, clicking on one of these anchor tags results in a call like this:

loadUserNameInfo(undefined);

Why is this? My goal is an anchor:

<a onclick="loadUserNameInfo(someguy)">someguy</a>

How can i do this?

Update . It works:

newAnchor.onclick = function () { loadUsernameInfo(this.innerHTML) };
newAnchor.innerHTML = mentions[i];
+3
source share
2 answers

The "i" link inside the closure for onclick handlers is a capture of the live "i" link. It is updated for each cycle, which affects all created shutters. When your while loop ends, "i" is just beyond the end of the references array, so it mentions [i] == undefined for all of them.

Do it:

newAnchor.onclick = (function(idx) {
    return function () { loadUsernameInfo(mentions[idx]) };
})(i);

"i" idx .

+7

i , , , , .

function fillInMentioned(mentions) { 
    var mentionList = document.getElementById("mention-list"); 
    mentionList.innerHTML = ""; 
    for (var i = 0; i < mentions.length; i++) { 
        var newAnchor = document.createElement("a"); 

        // Set the index as a property of the object 
        newAnchor.idx = i;
        newAnchor.onclick = function () { 
            // Now use the property of the current object
            loadUsernameInfo(mentions[this.idx]) 
        }; 

        // give this anchor the necessary content 
        newAnchor.innerHTML = mentions[i]; 

        var newListItem = document.createElement("li"); 
        newListItem.appendChild(newAnchor); 
        mentionList.appendChild(newListItem); 
    } 
    document.getElementById("mentions").setAttribute("class", "");  
} 
+2

Source: https://habr.com/ru/post/1733961/


All Articles