Many small closures versus a single large one

Currently, I have a Google Map set up with various event listeners attached to different elements. For example, I am adding events for a Point object like this:

google.maps.event.addListener(this.marker, 'click', (function(point) {
    return function(event) {
        alert(point.index);
    }})(this));

I have numerous events such as 'click', 'rightclick', 'doubleclick', and more that I need to handle.

Typically, when adding an event listener, I encapsulate only the current point within a closure. However, I am considering simplifying it to:

var point = this;

google.maps.event.addListener(this.marker, 'click', function(event) {
    alert(point.index);
});

I have hesitated to make this change due to a couple of reasons. Firstly, I've observed experienced individuals in JavaScript use "individual" closures, which makes me think there may be a valid reason for it.

Secondly, I am uncertain about how creating a large closure might affect performance by capturing unnecessary variables (e.g., 'var color') that are not required in my event function. Could this potentially lead to performance issues?

Any insights or advice on optimizing these event listeners would be greatly appreciated. Thank you!

Answer №1

Both instances demonstrate the creation of closures around a variable referred to as point. In the first scenario, point serves as a parameter for the outer anonymous function, whereas in the second case, point is a local variable. Nevertheless, both situations involve its encapsulation within an anonymous function.

Forming an anonymous function that takes a named parameter and promptly invokes it with an argument is just one method of associating a value with a specific name within a scope.

(function(x) { 
    // x now holds the assigned value
})(getValue());

Alternatively:

var x = getValue();
// x now contains the specified value

The distinction lies in utilizing a function to ensure that the variable x exists within its unique namespace, distinct from any other occurrences of x in the enclosing scope. This emphasizes maintainability over execution speed.

As for performance comparisons, conducting tests across various browsers is vital since each has its own execution engines.

One might assume that creating more anonymous functions leads to increased small allocations. Hence, the second example, with fewer anonymous functions, could potentially outperform the first. However, such assumptions are baseless without thorough testing on all relevant browsers.

Answer №2

As long as your point remains constant, there shouldn't be any issues with the code. Your second example should work just fine:

var point = this;

google.maps.event.addListener(this.marker, 'click', function(event) {
  alert(point.index);
});

In cases where your point may change and you need it to be in a specific state, like within a loop for instance, it's recommended to create another closure for your event handling function:

for(var i = 0, len = points.length; i < len; i++) {
  google.maps.event.addListener(points[i].marker, 'click', (function(point) {
    return function(event) {
      alert(point.index);
    }
  })(points[i]));
}

If you didn't use closures in this scenario, the event would have referenced the last elements of the array at the time it was triggered.

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

What are the steps for integrating connect-multiparty into route paths?

I am looking to incorporate connect-multiparty into my routes. Upon researching, I found the following example... var multipart = require('connect-multiparty'); var multipartMiddleware = multipart(); app.post('/upload', multipartMiddle ...

Can this pagination task be accomplished without the use of backgrid?

I have been exploring ways to implement server-side pagination similar to what Datatables offers, and during my search I came across the backbone.paginator library on GitHub. However, I am curious if there are any other options available as well. After ex ...

Having trouble fetching AJAX information from PHP

I'm currently developing a basic application that is designed to determine your current location, utilize AJAX to send the coordinates to a PHP file, and then compute distances in PHP to showcase nearby shops. Here is my JavaScript and AJAX code: $( ...

Ways to customize the bootstrap-datetimepicker to display time in 15-minute increments

Here is my code in JavaScript to increment by minutes at a 1-hour interval: fillMinutes = function () { var table = widget.find('.timepicker-minutes table'), currentMinute = viewDate.clone().startOf('h'), ...

Is it possible to convert an object and/or a nested array with objects into a JSON string without relying on JSON.stringify?

Struggling to generate a correct JSON string from an object without relying on JSON.stringify(). Presenting my current implementation below - var my_json_encode = function(input) { if(typeof(input) === "string"){ return '"'+input+&apo ...

Retrieve a single-page application (SPA) webpage using AJAX

I'm attempting to retrieve an entire webpage using JavaScript by entering the URL. However, the site is structured as a Single Page Application (SPA) that relies on JavaScript / backbone.js to load most of its content dynamically after the initial res ...

Modifying the class of multiple images within an array

I am excited to share my first post here and express my gratitude for all the solutions I have found on this platform. I encountered an issue with using .removeClass and .addClass in my recent program. I am loading multiple pictures into an array called F ...

Is it possible in AngularJS to automatically bind an onclick function from the dynamically generated object when utilizing ng-repeat?

I am facing an issue with binding a function from an array of items to an element using ng-repeat in AngularJS. One of the attributes on each item is a custom function, like this: item.myFunction = function(){ // do something } I tried various methods to ...

The designated redirection path, as indicated in the 'next.config.js' file for a particular project, has now been applied to all projects

Something strange is happening... I set a redirect path for the root index page in one of my projects and it worked perfectly, but now all of my other projects are also being redirected to that same path when I try to visit localhost:3000. It's alway ...

AngularJS framework may encounter an issue where changes in $scope data do not reflect in the view

I have noticed that when I reload the data using my function, the view does not change. After some research, I found that adding $scope.$apply() should solve this issue. However, I am encountering an error when trying to implement this solution. https://d ...

Understanding the specific purpose and functionality of the "next()" parameter in express.js

As a newcomer to express.js, I have been diving into the documentation to understand its nuances. One particular aspect that caught my attention is the next parameter in express middleware, which supposedly triggers the following middleware function for th ...

How can you identify the second least common integer in an array of numbers?

Seeking help with a JavaScript coding challenge that I'm stuck on, here is the question: Create a function that takes an array of integers and returns an element from that array. The function should calculate the frequency of each element (how many ...

ng-bind with the ability to store its own internal value

My server side code (GSP) is dynamically generating HTML for me in the following format: <span> <g:generateAmount /> </span> I am integrating this into an Angular controller and I want to be able to bind a scope variable to the span ...

Having trouble with filtering JSON data in AngularJS?

I'm sorry if this question has already been answered. I tried looking for solutions on other websites, but couldn't understand them. I am attempting to filter JSON data within the ng-repeat function, but whenever I try to input something, it does ...

I am facing issues with running my project due to a gyp error. Can anyone provide guidance on resolving this problem?

Every time I execute my code, I encounter the same persistent error. Despite attempting to resolve it by uninstalling and reinstalling Node and npm, the issue persists. Furthermore, the lack of "node_modules" exacerbates the problem. How can I rectify this ...

An issue was identified where a circular reference was encountered during the serialization process of an object belonging to the 'System.Reflection.RuntimeModule' in MVC JSON

I am working on displaying a table using Json, but I encountered an error. The error message says: "A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'" The code for Index.cshtml: var table ...

Ensure the presence of an HTML element in a directive when conducting unit tests

I have developed a custom directive called "generate-form-field-directive" that dynamically generates a form field based on the type received. Here is the code snippet for the directive - (function () { "use strict"; var app = angular.module("appModule" ...

angular2 angular-entity directive

I have developed a component that accepts a template: export class TemplateParamComponent implements OnInit { @Input() items: Array<any>; @Input() template: TemplateRef<any>; } Here is the HTML code: <template #defaultTemplate le ...

Exclude choices from dropdown menu if they have already been chosen in another option

I need help with a form that allows users to add additional states and text boxes for each added state. The goal is to prevent users from selecting the same state in multiple select boxes. <form action=state.php method=post> <a href="javascri ...

Leverage the power of the React useFetch hook with an onclick/event

My component utilizes a custom reusable hook for making HTTP calls. Here is how I am using it: const { data, error, isLoading, executeFetch } = useHttp<IArticle[]>('news', []); Additionally, within the same component, there is a toggle che ...