57185

javascript closure in a for loop [duplicate]

Question:

<blockquote>

<strong>Possible Duplicate:</strong><br /><a href="https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example" rel="nofollow">Javascript closure inside loops - simple practical example</a><br /><a href="https://stackoverflow.com/questions/5555464/javascript-closure-of-loop" rel="nofollow">Javascript: closure of loop?</a>

</blockquote>

so I would like the results to be 1,2,3 instead of 3,3,3. How do I set the context/scope so that the jobs are using the correctly scoped "i"?

function buildJobs(list) { var jobs = []; for (var i = 0; i < list.length; i++) { var item = list[i]; jobs.push( function() {alert(item)} ); } return jobs; } function testJobs() { var jobs = buildJobs([1,2,3]); for (var j = 0; j < jobs.length; j++) { jobs[j](); } }

Answer1:

Wrap the inner function with a another function that's immediately executed and receives i as an argument:

function buildJobs(list) { var jobs = []; for (var i = 0; i < list.length; i++) { var item = list[i]; (function(i) { jobs.push( function() {alert(list[i])} ); })(i); } return jobs; }

You're now closing over the i that is local to the wrapper function, which is a different variable in each iteration. (In your original configuration each inner function was closing over the <em>same</em> variable (whose value was 3 by the time any of the functions ever executed).)

Answer2:

When loops generate functions, they all share access to the same scope of variables. And there can only be one variable on the same name in a given scope. So they all use i from the loop, and use the current value of i when they execute. And after the loop runs, it will always be 3.

function buildJobs(list) { var jobs = []; for (var i = 0; i < list.length; i++) { (function(i) { var item = list[i]; jobs.push( function() {alert(item)} ); })(i); } return jobs; }

So introduce a new scope that captures the current value of i just for that iteration. You now have a new scope for each function generated, each with a different value for i.

Answer3:

function buildJobs(list) { var jobs = []; list.forEach( function( item ){ jobs.push( function(){ alert(item); }); }); return jobs; }

<a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach" rel="nofollow">forEach</a>

Recommend

  • JSF - Keep Faces Messages after redirect from @PostConstruct
  • SQL Server - Querying sysobjects
  • How should i track Objs in use, C#
  • How to create closure in loop and store it in variable for later execution
  • Maven LifeCycleExecutor with an incomplete configuration error
  • How to install and setup Testswarm?
  • Hudson - different build targets for different triggers
  • How do I get the number of jobs in a rq queue?
  • Is there any way to call saveCurrentTurnWithMatchData without sending a push notification?
  • Angular Bootstrap Carousel Slide Transition not working correctly
  • Multicolored edittext hint
  • Redux Form - Not able to type anything in input
  • Silverlight DependencyProperty.SetCurrentValue Equivalent
  • How to use JavaScript to determine whether a file exists in a directory?
  • How can I sort a a table with VBA with given text condition?
  • Functions in global context
  • FileReader+canvas image loading problem
  • All Classes Conforming to Protocol Inherit Default Implementation
  • Compare two NSDates in iPhone
  • How to delete a row from a dynamic generate table using jquery?
  • using HTMLImports.whenReady not working in chrome
  • Java static initializers and reflection
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • Change div Background jquery
  • Turn off referential integrity in Derby? is it possible?
  • Authorize attributes not working in MVC 4
  • Bitwise OR returns boolean when one of operands is nil
  • Add sale price programmatically to product variations
  • EntityFramework adding new object to nested object collection
  • Is there any way to bind data to data.frame by some index?
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • How can I use `wmic` in a Windows PE script?
  • Unable to use reactive element in my shiny app
  • Net Present Value in Excel for Grouped Recurring CF
  • How to push additional view controllers onto NavigationController but keep the TabBar?
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?
  • How do I use LINQ to get all the Items that have a particular SubItem?