Is there a better way to create an object-oriented class with jQuery?

JavascriptJquery

Javascript Problem Overview


I use the jQuery extend function to extend a class prototype.

For example:

MyWidget = function(name_var) {
  this.init(name_var);
}

$.extend(MyWidget.prototype, {
   // object variables
   widget_name: '',

   init: function(widget_name) {
     // do initialization here
     this.widget_name = widget_name;
   },

   doSomething: function() {
     // an example object method
     alert('my name is '+this.widget_name);
   }
});


// example of using the class built above
var widget1 = new MyWidget('widget one');
widget1.doSomething();

Is there a better way to do this? Is there a cleaner way to create the class above with only one statement instead of two?

Javascript Solutions


Solution 1 - Javascript

I quite like John Resig's Simple JavaScript Inheritance.

var MyWidget = Class.extend({
  init: function(widget_name){
    this.widget_name = widget_name;
  },

  doSomething: function() {
    alert('my name is ' + this.widget_name);
  }
});

NB: The "Class" object demonstrated above isn't included in jQuery itself - it's a 25 line snippet from Mr. jQuery himself, provided in the article above.

Solution 2 - Javascript

Why not just use the simple OOP that JavaScript itself provides...long before jQuery?

var myClass = function(){};
myClass.prototype = {
    some_property: null,
    some_other_property: 0,

    doSomething: function(msg) {
        this.some_property = msg;
        alert(this.some_property);
    }
};

Then you just create an instance of the class:

var myClassObject = new myClass();
myClassObject.doSomething("Hello Worlds");

Simple!

Solution 3 - Javascript

To summarise what I have learned so far:

Here is the Base function that makes Class.extend() work in jQuery (Copied from Simple JavaScript Inheritance by John Resig):

// Inspired by base2 and Prototype
(function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};

  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;

    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;

    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;
       
            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];
       
            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);       
            this._super = tmp;
       
            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }

    // Populate our constructed prototype object
    Class.prototype = prototype;

    // Enforce the constructor to be what we expect
    Class.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;

    return Class;
  };
})();

Once you have run executed this code, then that makes the following code from insin's answer possible:

var MyWidget = Class.extend({
  init: function(widget_name){
    this.widget_name = widget_name;
  },

  doSomething: function() {
    alert('my name is ' + this.widget_name);
  }
});

This is a nice, clean solution. But I'm interested to see if anyone has a solution that doesn't require adding anything to jquery.

Solution 4 - Javascript

jQuery doesn't offer that. But Prototype does, via Class.create.

Solution 5 - Javascript

This is long gone dead, but if anyone else searches for jQuery creating class - check this plugin: http://plugins.jquery.com/project/HJS

Solution 6 - Javascript

I found this website a impressive one for oops in javascript Here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDevonView Question on Stackoverflow
Solution 1 - JavascriptJonny BuchananView Answer on Stackoverflow
Solution 2 - JavascriptPaul AllsoppView Answer on Stackoverflow
Solution 3 - JavascriptDevonView Answer on Stackoverflow
Solution 4 - JavascriptnoahView Answer on Stackoverflow
Solution 5 - Javascriptola l martinsView Answer on Stackoverflow
Solution 6 - JavascriptSam Arul Raj TView Answer on Stackoverflow