skip to Main Content

Let’s assume I have the following code:

(function () {

    const largeObject = provideSomeLargeObject();
    const largeStaticListOfElements = document.querySelectorAll('span');
    const someElementThatWillBeRemoved = document.getElementById('i-will-be-removed');

    const elms = document.getElementsByClassName('click-me');

    for (let i = 0; i < elms.length; ++i) {

        const anotherLargeObject = provideAnotherLargeObject();

        elms[i].addEventListener('click', function (e) {
            // callback just uses i, which contains a literal value
            e.preventDefault();
            console.log(i);
        });
    }

    // largeObject, largeStaticListOfElements, someElementThatWillBeRemoved, and anotherLargeObject
    // are no longer used in this code. Should they be set to null to allow GC them?

})();

The event listeners create function scopes, and after executing the above code, the event listeners still exist, thus the outer function scopes are preserved so that the event handlers can use the variables they contain.

However, the event handlers just use some literal value from the outer scopes, but in these scopes there are other variables, that are not used anymore.

  • Would the event listeners prevent garbage collecting the objects referenced by these variables, so I have to manually assign null to the variables at the end of the code,
  • or are JavaScript engines smart enough to detect that the event handler never uses the variables, so the referenced objects can be GC even if the variables reside in a still existing function scope?

2

Answers


  1. It’s not so much the event listeners, but how you declare each and every identifier throughout.

    So if you’re seriously concerned about the Garbage Collector doing its job (and you should be), you might want to refrain from declaring everything as constants, unnecessarily!

    Examples of GOOD constant declarations…

    const DaysOfWeek=['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
    
    const MyName='John Citizen';
    
    const CompanyHome='https://ourcompany.com/';
    

    Examples of BAD constant declarations…

    const largeObject = provideSomeLargeObject();
    
    const largeStaticListOfElements = document.querySelectorAll('span');
    
    const someElementThatWillBeRemoved = document.getElementById('i-will-be-removed');
    
    const elms = document.getElementsByClassName('click-me');
    

    You get the drift…

    NB: The Garbage Collector CANNOT collect constant declarations for they are pushed to the top of the code section by the O/S, where their exact size is preserved in memory throughout the page running, given that they can never grow or shrink in size; for they can never change their value.

    Login or Signup to reply.
  2. Note that variables come in 2 flavors – primitives and objects. Primitives exists in a scope, you can’t reference them outside its own and child scopes (they are copied by value).

    So in your example you just don’t care since you use a primitive only. If you remove event listeners or remove the elements from DOM, the whole construct is garbage collected (if the elements aren’t referenced elsewhere).

    If you use objects and reference them outside the scope, you are in trouble and use reference = null for all outside references so the construct is garbage collected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search