I have a page with products and a number of filter blocks to filter by size, colours, etc.
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.
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.