Can you clarify the concept of closures and how they bind the loop counter to the function scope?

I have observed programmers setting up event listeners inside loops, utilizing the counter. The syntax that I have come across is as follows:

for(var i=0; i < someArray.length; i++){
   someArray[i].onclick = (function(i){/* Some code using i */})(i);
}

I am curious about the reasoning behind this approach and the peculiar syntax used here. This is new to me:

(function(i))(i);

Thank you in advance for taking the time to explain this.

Answer №1

The technique of using (function(i))(i) creates an anonymous function and then immediately runs it.

This is commonly done to generate a unique function each time the loop iterates, ensuring that each event handler has its own version of the variable instead of all event handlers sharing the same one.

For instance:

for(int i = 0; i < 10; i++)
    buttons[i].click = function() { doFoo(i); };

This scenario can be confusing for many people, as clicking any button will trigger doFoo(10).

On the contrary:

for(int i = 0; i < 10; i++)
    buttons[i].click = (function(i){ return function() { doFoo(i); };)(i);

Each iteration generates a new variant of the inner function (with its specific value of i), ensuring proper functionality.

Answer №2

One reason for this is due to the fact that JavaScript operates under function scope, not block scope. This means that any variable you declare within a loop will be within the function's scope, allowing every closure to access the same variable.

In order to create a new scope, it is necessary to invoke a function, which is exactly what

(function(i){/* Some code using i */}(i))

accomplishes.

It is important to note that in your example, a crucial component is missing: The immediate function must return another function that serves as the click handler:

someArray[i].onclick = (function(i){
    return function() {
       /* Some code using i */
    }
}(i));

The immediate function is essentially just a way to combine function definition and function call. It can also be replaced by a regular function call:

function getClickHandler(i) {
    return function() {
         /* Some code using i */
    }
}

for(var i=0; i < someArray.length; i++){
   someArray[i].onclick = getClickHandler(i);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting an if isset statement below can be achieved by checking if the variable

I have included a javascript function below that is designed to display specific messages once a file finishes uploading: function stopImageUpload(success){ var imagename = <?php echo json_encode($imagename); ?>; var result = '& ...

Unable to retrieve the sum total of all product items and display it in the designated text element

My product items are dynamically generated in a list. I have used the calculateItemTotal() method to determine the total for each item. Now, I need to sum up all these item totals and display the result in the total text field. However, instead of showing ...

Sending asynchronous requests to handle data within various functions based on different links

I'm currently facing a major roadblock when it comes to resolving my issues with callbacks. I've gone through resources like How to return value from an asynchronous callback function? and How to return the response from an Ajax call?, among seve ...

Ensure to preselect the radio button based on the Day's value

I have set up my Radio buttons with corresponding content to be displayed when clicked. I want to automatically pre-select the tab button based on the current day. For example, if today is Sunday, the page should load showing the contents for Sunday. If i ...

Enhance an item by introducing additional properties derived from its current key-value pairs

I have a task of converting the following object: myObj = { "pageName": "home", "dataExtract": "data1|data2=value2|data3=value3|data4=value4a,value4b,value4c"} Into this format: myObjMod = { 'pageName': 'home', 'dataExtract&apos ...

The Angular scope fails to reflect changes on the view

In this angular ng-click event, I have the following code: eventApp.controller('DetailEventController', ['$scope', '$http', '$compile', '$timeout', function ($scope, $http, $compile, $timeout, uiCalendarCon ...

The JSON.stringify() function helps to convert data into a JSON-formatted string, avoiding any potential "c

connection.query( 'SELECT DeskName FROM desks WHERE stat = ?',["Booked"], function(err, rows){ if(err) { throw err; }else{ try{ var dataToParse = new Array(); dataToParse = rows; res.render('workspaces.html',{parsedArray : JS ...

Unlock the power of polymer iron-ajax by seamlessly linking input element data to the iron-ajax's body attribute

Having some trouble binding data from an input element to the "body" attribute of iron-ajax. In the past, using core-ajax in Polymer 0.5, I could easily bind values like so: <core-ajax id="ajax" method="POST" contentTy ...

Extract information from a webpage using Selenium WebDriver

Currently, I am working on mastering Selenium, but I have hit a roadblock that I need assistance with. My task is to gather all the betting information for games from the following link and store it into an array. Given my limited experience with HTML an ...

What is the significance of the error message '[WDS] Disconnected!' in the context of using webpack and Vue.js?

Currently, I am engaged in a Django project that utilizes Vue.js for the frontend. Whenever I refresh the page, I encounter the "[WDS] Disconnected!" error. Despite the website's full functionality and absence of issues, this error appears every time ...

Angular code is malfunctioning and not delivering the expected results

I currently have setup the code below: var videoControllers = angular.module('videoControllers', []); videoControllers.videoControllers('VideoDetailController', function($scope, $routeParams, $http){ $http.get('http://localho ...

Is there a way to download a file using an ajax request?

We are faced with a particular scenario in our application where: Client sends a request Server processes the request and generates a file Server sends the file back as a response Client's browser prompts a dialog for downloading the file Our appli ...

Creating a drawImg function on the HTML/JavaScript canvas

Attempting to duplicate a specified section of an image onto a canvas below, but finding that the mirrored section is resizing unexpectedly. For example, if given a map image and trying to replicate a building from it exactly below, why does the mirrored s ...

How can I utilize match props in React JS with the Context API?

Currently working on a basic application that utilizes context API, fetch, and react hooks for all components except the context API component due to ongoing learning of hooks. The challenge lies in incorporating the match prop within the context API prov ...

WebApp specifically designed for iPads that mimics the functionality of a swipe

I am in the process of developing a full-screen web application for an iPad that will showcase a series of images in a slider format. The users should be able to swipe between the images and click on one to view it in detail. Below is an example showcasin ...

iterative outcomes with ajax and jquery scripting in javascript

Hey there! I'm trying to create a JavaScript script using AJAX that will extract the id and value of a button when hovered over. The extracted value will then be sent to a PHP script on the same page, where it will be used as a variable for searching ...

Transferring information between two separate components

Hey there, I'm struggling with the Payment Component. What I want to achieve is that when I click on a link, it transfers (ClassG, imageG, and PriceG) to the Payment Component where I can then style them accordingly. I've attempted something, but ...

Determine the total of all the values displayed in the footer of a jQuery

I am looking to show the total amount in the footer of a jquery datatable. Below is a snapshot of my datatable: https://i.stack.imgur.com/z01IL.png Here is the code snippet for my jquery datatable: for (var i = 0; i < length; i++ ) { var patient = ...

How can complex POST parameters be structured in a RESTful API?

For my current project, I am working on developing an application utilizing node.js along with express. This application involves a feature that allows users to subscribe to lists of items. Each subscription includes specific options such as minimum scores ...

When a button is clicked, load two separate pages into two distinct divs at the same time

$('#menuhome').click(function(){ $('#leftcolumncontainer').load('pages/homemenu.php'); }); the code above is used to load the home menu on the left side. Now, let's add the following: $('#menu ...