Working with JavaScript Objects
How a tricky bug led me to learn even more about JavaScript
Coding Computer by Lukas is licensed under Creative Commons Zero
TIL that when you have a plain object and store instance variables on it, you’re actually setting a class variable across all instances.
For example:
utils.fancyForm = {
$element: null,
$fields: null,
init: function(element) {
this.$element = $(element);
this.$fields = $(":input", this.$element);
return this;
}
}
If you attempt to save and reference that object more than once on the page, the variables $element
and $fields
will always be set from the latest call to init
. This happens no matter what instance you’re working with. In order to have truly separate instances with their own instance variables, you need to make an object with a prototype, i.e.:
FancyForm = function(element) {
this.$element = $(element);
this.$fields = $(":input", this.$element);
}
FancyForm.prototype = {
$element: null,
$fields: null,
}
utils.fancyForm = {
init: function(element) {
return new FancyForm(element);
}
}
The first item is the object’s constructor, and it is simply the init
function from the original version. The prototype is effectively all the things that were in the original object. In order to maintain backwards compatibility in the rest of the codebase, we keep the utils.fancyForm
helper around with the init
method that simply returns an instantiation of the new FancyForm
object.
Now, when we call utils.fancyForm.init(element)
and bind them multiple times on the same page, each one will act completely independent of one another, as we want and expect.
Comments