How am I misunderstanding JavaScript closure resolution in this example?
I thought I understood JavaScript closures but apparently I don't. Take the following excerpt from my code:
for(var i=0; i<data.List.length; i++) {
var entry = data.List[i]; // I thought this line should have resolved the issue?
$('<tr class="logs-list-item"><td class="lefticon nowrap"><a href="javascript:void(0)"></a></td><td class="right nowrap"></td></tr>')
.appendTo(tbody)
.find('a').text(entry.Text)
.click(function() {
alert(entry.Text + ' ' + entry.Filename);
showLog(id, entry.Filename);
})
.closest('tr').find('td:last').text(entry.When);
}
As you can see, we're iterating through a list of filename entries and adding a table row for each entry with a bit of text describing the file and an onclick handler for each entry that is supposed to call a function showLog()
with the details of the selected filename.
What is actual开发者_StackOverflow社区ly happening is that all of the rows are adding correctly but every one of them is being assigned a handler for the last item in the list.
On line #2 I am defining a variable inside the for loop and accessing that variable within the closure, but it ultimately doesn't seem to be resolving correctly when the function is actually called.
Any ideas what I'm doing wrong?
Javascript does not have block-level scoping.
Even though the variable is defined inside the loop, it's still shared.
You need to move the loop body to a separate function.
For this to work you need to use something like this:
for(var i=0; i<data.List.length; i++) {
(function(entry){
// your code goes here
})( data.List[i] );
}
Can you try that code please?
function generateClickHandler(entry) {
return function() {
alert(entry.Text + ' ' + entry.Filename);
showLog(id, entry.Filename);
}
}
..click(generateClickHandler(entry))...
精彩评论