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.

Photo of Joshua Kovach

Josh’s skills include web and mobile development and he enjoys developing APIs and Android Apps. He is also a mentor on HackHands, pairing with programmers working through coding issues.

Comments