Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Can Javascript classes/objects have constructors and how are they created? Any examples?

share|improve this question
   
9  
new link – Guillaume Massé Apr 19 '12 at 4:49

10 Answers

up vote 109 down vote accepted

Original answer:

function Box(color)
{
   this.color = color;

   this.getColor = function()
   {
       return this.color;
   }
}

Alternative where color resembles a private member variable:

function Box(col)
{
   var color = col;

   this.getColor = function()
   {
       return color;
   }
}

Usage:

var blueBox=new Box("blue");
alert(blueBox.getColor()); //will alert blue

var greenBox=new Box("green");
alert(greenBox.getColor()); //will alert green
share|improve this answer
Thanks :). – Click Upvote Jul 12 '09 at 11:24
Is it necessary to prefix all of member fields with "this." inside the object, or is that just because the member is named the same as the constructor parameter (color)? – Boris B. Jun 14 '12 at 9:10
2  
@BorisB, yes you do - this defines color and getColor on the Box object, otherwise you're assigning variables in the usual scope. – Nick Jun 15 '12 at 16:23
1  
@Jeach yes it does. I've provided an alternative snippet that hides color. I'd suggest which you use is largely down to personal preference (protection vs. simplicity) – Nick Jun 24 '12 at 12:43
2  
@CamiloMartin Although not always necessary, making a variable "private" (or in this case, unnameable) can be a useful way to prevent external code becoming dependent on the implementation details of your class. Even just the indication of which elements of the class are public/private can be useful to external users. – Nick Sep 18 '12 at 21:39
show 8 more comments

Here's a template I sometimes use for OOP-similar behavior in JavaScript. As you can see, you can simulate private (both static and instance) members using closures. What new MyClass() will return is an object with only the properties assigned to the this object and in the prototype object of the "class."

var MyClass = (function () {
    // private static
    var nextId = 1;

    // constructor
    var cls = function () {
        // private
        var id = nextId++;
        var name = 'Unknown';

        // public (this instance only)
        this.get_id = function () { return id; };

        this.get_name = function () { return name; };
        this.set_name = function (value) {
            if (typeof value != 'string')
                throw 'Name must be a string';
            if (value.length < 2 || value.length > 20)
                throw 'Name must be 2-20 characters long.';
            name = value;
        };
    };

    // public static
    cls.get_nextId = function () {
        return nextId;
    };

    // public (shared across instances)
    cls.prototype = {
        announce: function () {
            alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
                  'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
        }
    };

    return cls;
})();

I've been asked about inheritance using this pattern, so here goes:

// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
    // We use an intermediary empty constructor to create an
    // inheritance chain, because using the super class' constructor
    // might have side effects.
    var construct = function () {};
    construct.prototype = superCls.prototype;
    cls.prototype = new construct;
    cls.prototype.constructor = cls;
    cls.super = superCls;
}

var MyChildClass = (function () {
    // constructor
    var cls = function (surName) {
        // Call super constructor on this instance (any arguments
        // to the constructor would go after "this" in call(…)).
        this.constructor.super.call(this);

        // Shadowing instance properties is a little bit less
        // intuitive, but can be done:
        var getName = this.get_name;

        // public (this instance only)
        this.get_name = function () {
            return getName.call(this) + ' ' + surName;
        };
    };
    inherit(cls, MyClass); // <-- important!

    return cls;
})();

And an example to use it all:

var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"

var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"

alert(john instanceof MyClass); // true

As you can see, the classes correctly interact with each other (they share the static id from MyClass, the announce method uses the correct get_name method, etc.)

One thing to note is the need to shadow instance properties. You can actually make the inherit function go through all instance properties (using hasOwnProperty) that are functions, and automagically add a super_<method name> property. This would let you call this.super_get_name() instead of storing it in a temporary value and calling it bound using call.

For methods on the prototype you don't need to worry about the above though, if you want to access the super class' prototype methods, you can just call this.constructor.super.prototype.methodName. If you want to make it less verbose you can of course add convenience properties. :)

share|improve this answer
6  
Just a note about the cls.prototype part: "shared across instances" is only for reading the value (calling announce). If you set myClassInstance.announce to another value, it creates a new property in myClassInstance, so it only applies to that object, not other instances of the class. Assigning to MyClass.prototype.announce will affect all instances though. – Matthew Crumley Jul 11 '09 at 18:55
@Blixt - have used your example extensively - thanks! – cc young Jul 20 '11 at 13:12
No problem, glad to be of help! :) – Blixt Jul 20 '11 at 18:50
2  
Thank you! Very Liked! Could you show example of class inheritance in this approach. – Dmitrij Golubev Oct 15 '12 at 11:29
1  
@DmitrijGolubev, Brad Dwyer, and Nathan C. Tresch: I've added inheritance, but it's getting pretty complicated so I would usually advice you to go with a simpler solution, unless you need such hardcore inheritance in JavaScript (which is really just a prototypal language). – Blixt Nov 27 '12 at 18:37
show 3 more comments

It seems to me most of you are giving example of getters and setters not a constructor, ie http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming).

lunched-dan was closer but the example didn't work in jsFiddle.

This example creates a private constructor function that only runs during the creation of the object.

var color = 'black';

function Box()
{
   // private property
   var color = '';

   // private constructor 
   __construct = function() {
       alert("Object Created.");
       color = 'green';
   }()

   // getter
   this.getColor = function() {
       return color;
   }

   // setter
   this.setColor = function(data) {
       color = data;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange');

alert(b.getColor()); // should be orange

alert(color); // should be black

If you wanted to assign public properties then the constructor could be defined as such:

var color = 'black';

function Box()
{
   // public property
   this.color = '';

   // private constructor 
   __construct = function(that) {
       alert("Object Created.");
       that.color = 'green';
   }(this)

   // getter
   this.getColor = function() {
       return this.color;
   }

   // setter
   this.setColor = function(color) {
       this.color = color;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange'); 

alert(b.getColor()); // should be orange

alert(color); // should be black
share|improve this answer
3  
How is this not the #1 answer? Only Jon created a constructor with parameters. – Rap Aug 30 '12 at 14:29
Is there any way we can get an example of inheritance using this paradigm for constructors? – Nathan C. Tresch Nov 26 '12 at 22:26
What is the reason to have private constructor here? – Alexander Stepaniuk Dec 31 '12 at 18:23
@Rap Jon's constructor example has no parameters as it is Box() function :) . But this example as well as examples in the other answers can be easy extended to accept parameters. – Alexander Stepaniuk Dec 31 '12 at 18:28

So what is the point of "constructor" property? Cannot figure out where it could be useful, any ideas?

The point of the constructor property is to provide some way of pretending JavaScript has classes. One of the things you cannot usefully do is change an object's constructor after it's been created. It's complicated.

I wrote a fairly comprehensive piece on it a few years ago: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html

share|improve this answer
Hi! Thanks for the article. That's more clear now. – igor May 10 '11 at 10:03

Here are a couple of excellent explanations:

share|improve this answer
Sorry, but the explanations are not even close to be as good as the by @Joost and Douglas at javascript.crockford.com/inheritance.html They just don't give the full picture, e.g. difference of .prototype vs. [[prototype]]? – Yauhen Yakimovich Feb 17 at 17:58

I guess I'll post what I do with javascript closure since no one is using closure yet.

var user = function(id) {
  // private properties & methods goes here.
  var someValue;
  function doSomething(data) {
    someValue = data;
  };

  // constructor goes here.
  if (!id) return null;

  // public properties & methods goes here.
  return {
    id: id,
    method: function(params) {
      doSomething(params);
    }
  };
};

Comments and suggestions to this solution are welcome. :)

share|improve this answer
A couple comments: 1) statement if (!id) is not safe, values like 0 or false will cause it to evaluate true and return null. I'm guessing you want to check for undefined or null in which case === null and === undefined would be better. 2) This more closely resembles the Module pattern (adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth) versus a constructor, the difference being a Module returns an Object from the function whereas a constructor creates an object when paired with the new keyword, and in that case you would be setting values on 'this' instead of an object. – Rich Feb 25 at 20:30

Using Nick's sample above, you can create a constructor for objects without parameters using a return statement as the last statement in your object definition. Return your constructor function as below and it will run the code in __construct each time you create the object:

function Box()
{
   var __construct = function() {
       alert("Object Created.");
       this.color = 'green';
   }

  this.color = '';

   this.getColor = function() {
       return this.color;
   }

   __construct();
}

var b = new Box();
share|improve this answer
function MyClass(){}

is a constructor. When you do var myObj = new MyClass();

the MyClass is executed and a new object is returned of that class.

share|improve this answer
To clarify, what this means is at the top of your class you can say alert(valuePassedInAsArgument); and this will run once for each instantiation, so the whole class is the constructor itself. – Martin Lyne Nov 8 '12 at 15:19

This pattern has served me well. With this pattern, you create classes in separate files, load them into your overall app "as needed".

// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};

// "Package" 
// Similar to how you would establish a package in other languages
(function() {

// "Class"
var MyClass = function(params) {
    this.initialize(params);
}

    // "Global" vars (all instances);
    MyClass.counter = 0;

    // "Private" vars
var p = MyClass.prototype;

    p.id = null;
    p.firstname = null;
    p.lastname = null;

    p.initialize = function(params){
        this.id = MyClass.counter++;
        this.firstname = params.firstname;
        this.lastname = params.lastname;
    }

    p.doAlert = function(theMessage){
        alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id);
    }


// Assign class to app
myApp.MyClass = MyClass;

// Close the "Package"
}());

// Usage example:
var bob = new myApp.MyClass({   firstname   :   "bob",
                                lastname    :   "er"
                            });

bob.doAlert("hello there");
share|improve this answer
Those are instance variables but they have "public" accessibility, not "private" as in C++ or Java. – Potatoswatter Dec 7 '12 at 16:05
How would you go about creating a private variable (in the classic sense) that is relative to the instance, but not common common to all instances? – bob Jan 9 at 8:31
See Douglas Crockford's site, he's one of the language designers and a foremost authority. I don't always follow his patterns, but in general a private variable is a local var in the constructor (or function argument, or in a constructor-like function). – Potatoswatter Jan 9 at 8:34
Thanks for the tip... the following page explains what I was looking for: javascript.crockford.com/private.html – bob Jan 9 at 8:53
Oh, sorry for not testing the link :P – Potatoswatter Jan 9 at 9:40
show 1 more comment

I found this tutorial very useful. This approach is used by most of jQuery plug-ins.

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

var Class = function(methods) {   
    var klass = function() {    
        this.initialize.apply(this, arguments);          
    };  

    for (var property in methods) { 
       klass.prototype[property] = methods[property];
    }

    if (!klass.prototype.initialize) klass.prototype.initialize = function(){};      

    return klass;    
};

Now ,

var Person = Class({ 
    initialize: function(name, age) {
        this.name = name;
        this.age  = age;
    },
    toString: function() {
        return "My name is "+this.name+" and I am "+this.age+" years old.";
    }
}); 

var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.