JavaScript Classes – Best Practices for Working with Classes

classcode-qualityjavascript

Comparable questions have surely been asked before but I'd like to hear some words about my specific way of implementing Javascript classes.

Let me first start with a Javascript example taken from a real-life application I've been working on recently.

Example

PageControl= new function() {
  var self= this;

  // example additional control bound to page control
  var grid= new GridControl();

  self.initialise= function() {
    // initialise form fields, controls etc.
  };

  // example function
  self.load= function(id) {
    // reloads form with new data
  };

  $(document).ready(function() {
    self.initialise();
  });
};

Each page has its own PageControl instance with specific tasks solely relevant for the given page.

Question:

I'm not looking for alternative ways of how to implement it, I'd just want to know if the above example is bad or wrong code. The above structure has worked great so far, even if I work with sub controls like PageControl.grid.reload(); but I don't want to stick to error-prone code.

Best Answer

I'm not sure if it's bad or wrong, but it is confusing.

Your PageControl is not a class, it's an instance of an anonymous class. In javascript a class is a function object intended to be used with the new keyword to create instances of that class.

Your code uses the new keyword on an anonymous function.

What you're trying to accomplish, I think, is usually done using the IIFE (Immediately-invoked function expression) pattern.

PageControl= (function() {
  // you can create private variables and functions for use between your
  // functions, or add them to the self object to make them available.

  // example additional control bound to page control
  var grid= new GridControl();

  // Create your singleton w/ its member functions and possibly other properties
  // these functions can use 'this' to reference other members of the self object.
  // do it here so it can be referenced in the function closure used by
  // $(document).ready
  var self = {
    initialise: function() {
      // initialise form fields, controls etc.
    },

    load: function(id) {
      // reloads form with new data
    },

    // example additional control bound to page control
    grid: grid
  };

  $(document).ready(function() {
    self.initialise();
  });

  return self;      
})();

// your page can call those methods on the PageControl
PageControl.load("myId");
PageControl.grid.reload();

The key to the IIFE pattern is that you define a function expression that returns an object and then immediately call (execute) that function (function() {})();.

Related Topic