Search code examples
javascriptclassobjectgarbage-collectioninstance

JavaScript classes and not storing instances in variables: Will garbage collection cause any problems with this code?


I have a page with products and a number of filter blocks to filter by size, colours, etc.

enter image description here

To keep everything simple, this is a sample of the HTML of every filter block:

<div id="divFilterSizes">
    <h1>Sizes</h1>

    <input id="chkFilter_2xl" type="checkbox" value="2xl">
    <label for="chkFilter_2xl">2XL</label>
    <br />
    <input id="chkFilter_3xl" type="checkbox" value="3xl">
    <label for="chkFilter_3xl">3XL</label>

    <button data-filter type="button"><span>FILTER</span></button>
</div>

For every filter, I am creating an instance of the below class. I understand everything is private and all the code is inside the class but I like to do it this way to have a state for every filter block I have on the page, like for example the currentSelection variable, I know that at any time I can get all the selected filters for a specific filter block without having to loop the checkboxes each and every time:

<script>

    class Filter
    {

        #currentSelection;
        #filterElement;
        #filterButton;

        constructor(filterElement)
        {
            this.#filterElement = filterElement;
            this.#currentSelection = "";
            this.#filterButton = this.#filterElement.querySelector("[data-filter]");

            this.#filterElement.querySelectorAll("input[type=checkbox]").forEach(filterItem =>
            {
                filterItem.addEventListener("change", event => this.#OnFilterItemChange(event));                
            });
            
            this.#filterButton.addEventListener("click", event => this.#Filter(event));
        };
        

        #OnFilterItemChange(event)
        {       
            if (event.target.checked)
            {
                this.#currentSelection += event.target.value + "|";

                return;
            }

            this.#currentSelection = this.#currentSelection.replace(event.target.value + "|", "");
        };


        #Filter()
        {
            alert(`You selected ${this.#currentSelection}`);
        };

    };

</script>

This is how I am creating the instances:

<script>new Filter(document.getElementById('divFilterSizes'));</script>

Since I am not storing the instance in a variable, will I have issues with garbage collection, such as the user clicking the "FILTER" button and nothing happens because the instance has been removed?

I did consider switching to functions to play it safe but I find the class code much more cleaner since I have 5+ filter blocks and the advantage of state is a big bonus.


Solution

  • It seems you only instantiate this class because you want to set up listeners in the constructor. For all intents and purposes, constructor is a function that operates within the context of a newly created object. While the object will not be available to you directly, the methods will still be reachable because a reference to them lives in the listeners you set up. In this case, calling new Filter(...) is an equivalent of creating a calling a function setupFilterListeners(). I don't think the object would be collected, but it doesn't matter since you won't have access to it either way. I think you should save it in a variable - just in case you need it down the line. No reason not to.