407

Can JavaScript classes/objects have constructors? How are they created?

Ry-
  • 218,210
  • 55
  • 464
  • 476
Ali
  • 261,656
  • 265
  • 575
  • 769

19 Answers19

410

Using prototypes:

function Box(color) // Constructor
{
    this.color = color;
}

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

Hiding "color" (somewhat 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
Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85
Nick
  • 7,700
  • 2
  • 29
  • 37
  • 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 09:10
  • 3
    @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
    Why does everyone seem to always suggest putting 'this.' in front of variables? Doesn't this expose the variables without requiring (forcing) the use of setters and getters? – Jeach Jun 23 '12 at 21:34
  • 4
    @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
  • @Nick What I couldn't ever understand is "protection from what". – Camilo Martin Sep 02 '12 at 08:21
  • 6
    @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
  • @Nick `Even just the indication of which elements of the class are public/private can be useful to external users.` I see that it helps put the point across that consumers of the code should not fiddle with this or that detail of it, but it seems more of a concern to API/framework developers, and these usually publish documentation along with the code. For non-API projects, I cannot see other reason than "it feels good to write clean code", which is a fair reason, but it isn't very natural in javascript in comparison with languages that have a `private` keyword. – Camilo Martin Sep 19 '12 at 09:04
  • @CamiloMartin This can be useful when working in a team too - as much as I wish my teammates' code was wonderfully documented, it rarely is (and to be fair, neither is mine). I agree about this not being very natural, although the question itself is about how to do class-based programming in JavaScript; You could argue this isn't all that idiomatic either. It's worth noting that the two examples have other behavioural differences too e.g. when enumerating a box object. (In the first example, an object will contain `color`, in the second example it won't.) – Nick Sep 19 '12 at 22:23
  • @Nick Ah, I see what you mean now, about teams :) – Camilo Martin Sep 20 '12 at 03:28
  • 49
    `var` makes a private variable. `this` makes a public variable – EhevuTov Sep 29 '12 at 16:09
  • 2
    @CamiloMartin data hiding is even useful when you're working on a large project by yourself. After some times passes you may not remember whether you should be accessing that variable from another scope. – Kelvin May 07 '13 at 20:21
  • @Kelvin well, that's a fair point too. I guess adding extra code for the sake of cleanliness is beneficial just like adding comments - it's extra work but it makes things more clear. – Camilo Martin May 07 '13 at 23:50
  • What's difference in creating constructors with `Foo = function(){...}` and `function Foo(){...}` ? – Alan Kis Oct 15 '13 at 21:01
  • 3
    @AlanKis (At least in some Javascript engines) the stack trace will in the anonymous function case not even mention `Foo`, while in the latter case it will know that it's `Foo` being called. Very helpful for debugging. – Joachim Isaksson Oct 21 '13 at 11:36
  • 3
    I don't really see why you'd want to create the getter inside the constructor. The problem with that technique, instead of using the prototype, is that each time you create an object of that type, you're duplicating the function, which uses more memory, is slower, etc. The prototype is the way you really create classes. – Alexis Wilke Apr 06 '14 at 00:28
  • Good point @AlexisWilke, I've updated the answer to use the prototype. – Nick Apr 08 '14 at 21:06
  • 2
    Subtle difference between first approach (`this.getColor`) vs second (`Box.prototype.getColor`). Former defines a new property on the Box _instance_, latter does on its _prototype_. So `(new Box('blue')).hasOwnProperty('getColor')` returns `true` with the first approach, but `(new Box('green')).hasOwnProperty('getColor')`returns `false` with the second. This becomes important when following common patterns to iterate an object's properties, e.g.: [Loop through JavaScript object](http://stackoverflow.com/questions/684672/loop-through-javascript-object?rq=1) – Mauricio Morales Jul 06 '15 at 11:23
247

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. :)

Blixt
  • 49,547
  • 13
  • 120
  • 153
  • 7
    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
  • 1
    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
  • I'd like to second @DmitrijGolubev's reqeust. This covers encapsulation nicely but I'd like to see an example of inheritance. – Brad Dwyer Nov 22 '12 at 13:22
  • 2
    @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
  • @Blixt this is nothing new in terms of concept but it's a great guide! I believe for once this should be the accepted answer has it covers all of the OO approach. – CarlosB Nov 06 '13 at 14:31
  • I like this alot! However, I find it hard to do more than two levels of inheritance. Like Animal -> Mammal -> Donkey. – Mikael Östberg Jan 10 '14 at 10:09
  • 1
    @guiomie It's a "public static" method so you would call it on the constructor function (the "class"), not the instance: `MyClass.get_nextId()` – Blixt May 28 '14 at 22:34
  • @Blixt if its only callable in the instance, shouldn't it be considered private et not public ? – guiomie May 29 '14 at 00:51
  • @guiomie It's callable from anywhere. You can do this from anywhere in the code: `MyClass.get_nextId()`, not just from the instance. So by definition it's public (accessible everywhere) and static (accessible via the class, without requiring an instance of the class). – Blixt May 29 '14 at 19:24
  • The down vote was accidental. I am not able to undo it.. I did an up. Sorry abt that. – Satish P Sep 16 '14 at 11:14
  • When using, make sure you don't do something like `var MyClass = new MyClass();`! (you'll only do it once) – Coder Jan 15 '15 at 10:10
  • Very nice answer ! But when I try to add some `prototype` on `MyChildClass` I got an error `Uncaught TypeError: child.anotherAnnounce is not a function` :/ – Arthur Dec 17 '16 at 21:37
  • **Fixed** by updating `inherit` and extending like so `construct.prototype = extend(superCls.prototype, cls.prototype)` (extend have to be defined) – Arthur Dec 17 '16 at 22:08
166

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 
   var __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 
   var __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
Jon
  • 2,236
  • 2
  • 17
  • 19
  • 45
    How is this not the #1 answer? Only Jon created a constructor with parameters. – Rap Aug 30 '12 at 14:29
  • 1
    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
  • 1
    @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
  • In this case, how can parameters be passed to the constructor? – Anderson Green Jul 28 '13 at 21:56
  • 2
    @AndersonGreen you can add a parameter to Box and then pass it to the private constructor as a function parameter. – Gautham C. Aug 12 '13 at 16:22
  • I like that your solution creates private members but they are only accessible in the (traditional) constructor closure. That is, they aren't accessible from the prototype, which is pretty important when creating javascript classes. – rjcarr Sep 19 '13 at 22:47
  • 1
    There's no need for "private constructors". Just do your construction in the `Box` function and you're good to go (it's still "private"). "Private" in Javascript just means accessible via lexical scope; no need to assign to members. Additionally: this code is wrong. It creates a global `__construct` variable, which is quite bad. `var` should be used to restrict the scope of `__construct`. – mattbasta Nov 15 '13 at 01:41
  • In this answer you can't call a method from within the constructor, as the methods have not yet been defined when the constructor is called. The constructor (or its execution) would have to be moved to the bottom of the 'class'. Any solution for that? – Robbert Dec 18 '13 at 15:21
  • 1
    @mattbasta, I added var before __contruct. – Jon Jan 17 '14 at 05:20
  • 1
    @Robbert, I have a more update version of this at http://jsfiddle.net/jzumbrun/k2Lpp/ that calls __contruct at the end – Jon Jan 17 '14 at 05:21
  • 1
    Thanks Jon, that's the method I've been using too for years now - calling the constructor at the end. I found this question when I tried to look for a prettier alternative. I would've liked JS to have a constructor up top that doesn't need an extra command to run, but I guess it's just not possible. – Robbert Jan 18 '14 at 12:02
  • It's not necessary to run _construct() function as the function Box itself is a constructor. Also, if you create many Box-es, then your this.getColor assignments are fired everytime. It's better to have Box.prototype.getColor public method. – Rodion Bykov Jul 08 '14 at 13:35
  • This answer is redundant and misleading. The function will do the exact same thing if you removed the immediately invoked function that your naming `__construct` and simply put the same code in the body of the constructor (a Javascript constructor is a named function, thats all). Example: `function Box(){ var color = ''; alert("Object Created."); color = 'green'; } var b = new Box(); //the 'Object Created.' alert is fired` – Sevin7 Dec 12 '14 at 10:31
  • @Sevin7 The lexical structure here is what is important in this answer. Many of us like to organize javascript in a "class" like structure like ES6 and most server languages do instead of the prototype pattern displayed in other answers. And in creating the "class" pattern the private method __construct defined at the top and then required to be called at the bottom is poly-filling in the constructor method to recreate this pattern that will exist in ES6. See constructor examples in ES6: http://javascriptplayground.com/blog/2014/07/introduction-to-es6-classes-tutorial/ – Jon Dec 19 '14 at 17:59
23

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

  • The point is to use the "new" keyword. "d = new Drofto()" creates an empty object and runs the Drofto function with said new object bounded as "this". The Drofto function is free to return anything, but it is customary to return something to be regarded as a member of the Drofto class. – Juan Lanus Dec 17 '14 at 12:47
16

Example here: http://jsfiddle.net/FZ5nC/

Try this template:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
  v1: null
 ,v2: null
 ,f1: function Name_Space_ClassName_f1(){}
}

//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;

//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>

You must adjust your namespace if you are defining a static class:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>

Example class:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
    this.Width = width;
    this.Height = height;
    this.Color = color;
}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
  Width: null
 ,Height: null
 ,Color: null
 ,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
    var canvas = document.getElementById(canvasId);
    var context = canvas.getContext("2d");
    context.fillStyle = this.Color;
    context.fillRect(x, y, this.Width, this.Height);
 }
}

//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;

//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
    return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
    return new Shape.Rectangle(50,25,'#ff0000');
}
</script>

Example instantiation:

<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");

var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);

var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);

Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>

Notice functions are defined as A.B = function A_B(). This is to make your script easier to debug. Open Chrome's Inspect Element panel, run this script, and expand the debug backtrace:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};

//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
    A.Func.That.Does.Not.Exist();
}

Fail.Test();
</script>
bitlather
  • 540
  • 5
  • 11
  • Example added. Also added information on improving debug output. – bitlather May 26 '13 at 02:21
  • 1
    Probably because it adds a needless level of complexity to the problem. It's hard to find the answer in your post because of the pedantic name spacing and static class declaration. Don't get me wrong, it's good information but it's certainly more confusing than helpful if you are trying to get a foot in the door on understanding. I'm halfway competent in JS and I barely understand what you're doing here, or why it's relevant to "How do I constructor?" – Bmo Sep 20 '13 at 18:28
  • 1
    Thanks for the insight, Bmo. It was a lengthy post, but it's because I don't understand the use of a constructor if it's not tied to a well defined object and static class implementation. When learning C++ or Java, you have to learn how to implement classes alongside how to implement constructors. Web dev has become much more enjoyable ever since I stumbled upon this method of writing javascript, and I just wanted to share. I moved the fiddle up to the top so it's easier to find. I hope that will clarify any confusion. – bitlather Sep 30 '13 at 00:23
  • 1
    @Bmo Are you serious that the two lines about namespace makes hard to find the constructor exactly below, especially given the comment Constructor - MUST BE AT TOP OF FILE? Providing an example with namespace is very welcome, the javascript dev community blindly ignores namespaces causing hard to find errors when names clash. It is sad to see that js devs think if they copy a piece of text from a post on the internet and does something similar to what they need their work is complete. – user3285954 Jan 01 '15 at 13:28
  • 1
    The major problem with js and web development in general is that most of the devs ignore all practices what the industry created in 50+ years and think if they can do an ajax call they are the king. So sad to see that took so many years to start using well known patterns and practices in javascript. – user3285954 Jan 01 '15 at 13:30
10

This is a constructor:

function MyClass() {}

When you do

var myObj = new MyClass();

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

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • 1
    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 08 '12 at 15:19
  • `new object is returned of that class` -- isn't it more like a new object is returned of that function? – Don Cheadle Jul 24 '15 at 15:53
  • in javascript functions are objects – Leo Apr 27 '16 at 16:49
9

Yes, you can define a constructor inside a class declaration like this:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
Bruno
  • 898
  • 14
  • 17
8

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);
}

    // "Private Static" vars 
    //    - Only accessible to functions in this class.
    //    - Doesn't get wiped out when we create a new instance.
    var countInstances = 0;
    var allInstances = [];

    // "Private Static" functions 
    //    - Same as above, but it's a function accessible 
    //      only to other functions in this class.
    function doSomething(){
    }

    // "Public Static" vars
    //    - Everyone has access.
    //    - Doesn't get wiped out when we create a new instance.
    MyClass.counter = 0;

    // "Public Static" functions
    //    - Same as above, but anyone can call this "static method".
    //    - Kinda like a singleton class situation.
    MyClass.foobar = function(){
    }

    // Public properties and methods are built into the "prototype"
    //    - This is how each instance can become unique unto itself.
    //    - Establishing "p" as "local" (Static Private) variable 
    //      simply so we don't have to keep typing "MyClass.prototype" 
    //      for each property and function.
var p = MyClass.prototype;

    // "Public" vars
    p.id = null;
    p.firstname = null;
    p.lastname = null;

    // "Private" vars
    //    - Only used by "this" instance.
    //    - There isn't "true" privacy for each 
    //      instance so we have to fake it. 
    //    - By tradition, we indicate "privacy"  
    //      by prefixing it with an underscore. 
    //    - So technically, anyone can access, but we simply 
    //      don't tell anyone about it (e.g. in your API)
    //      so no one knows about it :)
    p._foo = null;

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

    p.doAlert = function(theMessage){
        alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ".  Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
    }


// 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");
bob
  • 7,539
  • 2
  • 46
  • 42
  • Those are instance variables but they have "public" accessibility, not "private" as in C++ or Java. – Potatoswatter Dec 07 '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 09 '13 at 08:31
  • See [Douglas Crockford](http://crockford.net)'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 09 '13 at 08:34
  • Thanks for the tip... the following page explains what I was looking for: http://javascript.crockford.com/private.html – bob Jan 09 '13 at 08:53
  • Oh, sorry for not testing the link :P – Potatoswatter Jan 09 '13 at 09:40
  • Maybe you should add var inst = new MyClass(params); ? – Yauhen Yakimovich Feb 17 '13 at 18:14
8

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]"
anasanjaria
  • 1,308
  • 1
  • 15
  • 19
6

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. :)

O.O
  • 7,179
  • 1
  • 34
  • 32
  • 1
    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 (http://www.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 '13 at 20:30
5

Maybe it's gotten a little simpler, but below is what I've come up with now in 2017:

class obj {
  constructor(in_shape, in_color){
    this.shape = in_shape;
    this.color = in_color;
  }

  getInfo(){
    return this.shape + ' and ' + this.color;
  }
  setShape(in_shape){
    this.shape = in_shape;
  }
  setColor(in_color){
    this.color = in_color;
  }
}

In using the class above, I have the following:

var newobj = new obj('square', 'blue');

//Here, we expect to see 'square and blue'
console.log(newobj.getInfo()); 

newobj.setColor('white');
newobj.setShape('sphere');

//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());

As you can see, the constructor takes in two parameters, and we set the object's properties. We also alter the object's color and shape by using the setter functions, and prove that its change remained upon calling getInfo() after these changes.

A bit late, but I hope this helps. I've tested this with a mocha unit-testing, and it's working well.

Just Rudy
  • 700
  • 11
  • 28
4

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();
Dan Power
  • 1,141
  • 1
  • 12
  • 18
  • 1
    You're not returning the constructor function, you're just calling it. – David Conrad Jun 06 '13 at 16:55
  • If you try to use `this.getColor();` on the line above `alert("Object Created.");` nothing will be alerted. There'll be an error like "getColor is not defined". If you want construct to be able to call other methods in the object it needs to be defined after all the other methods. So instead of calling `__construct();` on the last line just define construct down there and put `()` after it to force it to auto-execute. – thinsoldier Jun 13 '13 at 17:14
  • Correction. Adding `()` to the end of the __construct definition still resulted in the error. I had to call `__construct();` on its own line like in the original code to avoid the error. – thinsoldier Jun 13 '13 at 17:28
3

They do if you use Typescript - open source from MicroSoft :-)

class BankAccount {
 balance: number;
 constructor(initially: number) {
 this.balance = initially;
 }
 deposit(credit: number) {
 this.balance += credit;
 return this.balance;
 }
}

Typescript lets you 'fake' OO constructs that are compiled into javascript constructs. If you're starting a large project it may save you a lot of time and it just reached milestone 1.0 version.

http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

The above code gets 'compiled' to :

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • I'm working on a large project and I'm trying to convince people that TypeScript will give us a running shoot. We'll see how that goes. – wootscootinboogie May 23 '14 at 12:29
  • @wootscootinboogie In one day (ending at 5.30am right now) I've got pretty far and pretty comfortable with it. I strongly recommend reading the spec through and while you can skip half of the real nitty gritty stuff you're doing yourself a favor reading it through at least once. this guy's videos are excellent https://www.youtube.com/user/basaratali/videos. good luck ) – Simon_Weaver May 23 '14 at 12:31
1

In JavaScript the invocation type defines the behaviour of the function:

  • Direct invocation func()
  • Method invocation on an object obj.func()
  • Constructor invocation new func()
  • Indirect invocation func.call() or func.apply()

The function is invoked as a constructor when calling using new operator:

function Cat(name) {
   this.name = name;
}
Cat.prototype.getName = function() {
   return this.name;
}

var myCat = new Cat('Sweet'); // Cat function invoked as a constructor

Any instance or prototype object in JavaScript have a property constructor, which refers to the constructor function.

Cat.prototype.constructor === Cat // => true
myCat.constructor         === Cat // => true

Check this post about constructor property.

Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41
0

While using Blixt's great template from above, I found out that it doesn't work well with multi-level inheritance (MyGrandChildClass extending MyChildClass extending MyClass) – it cycles on calling first parent's constructor over and over. So here is a simple workaround – if you need multi-level inheritance, instead of using this.constructor.super.call(this, surName); use chainSuper(this).call(this, surName); with the chain function defined like this:

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}
jan
  • 1
0

http://www.jsoops.net/ is quite good for oop in Js. If provide private, protected, public variable and function, and also Inheritance feature. Example Code:

var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public

    pri.className = "I am A ";

    this.init = function (var1)// constructor
    {
        pri.className += var1;
    }

    pub.getData = function ()
    {
        return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
        + ", ID=" + pro.getClassId() + ")";
    }

    pri.getClassName = function () { return pri.className; }
    pro.getClassName = function () { return pri.className; }
    pro.getClassId = function () { return 1; }
});

var newA = new ClassA("Class");

//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)

//***You can not access constructor, private and protected function
console.log(typeof (newA.init));            // undefined
console.log(typeof (newA.className));       // undefined
console.log(typeof (newA.pro));             // undefined
console.log(typeof (newA.getClassName));    // undefined
0

just to offer up some variety. ds.oop is a nice way to declare classes with constructors in javascript. It supports every possible type of inheritance (Including 1 type that even c# does not support) as well as Interfaces which is nice.

var Color = ds.make.class({
    type: 'Color',
    constructor: function (r,g,b) { 
        this.r = r;                     /* now r,g, and b are available to   */
        this.g = g;                     /* other methods in the Color class  */
        this.b = b;                     
    }
});
var red = new Color(255,0,0);   // using the new keyword to instantiate the class
dss
  • 470
  • 5
  • 12
0

Here we need to notice one point in java script, it is a class-less language however,we can achieve it by using functions in java script. The most common way to achieve this we need to create a function in java script and use new keyword to create an object and use this keyword to define property and methods.Below is the example.

// Function constructor

   var calculator=function(num1 ,num2){
   this.name="This is function constructor";
   this.mulFunc=function(){
      return num1*num2
   };

};

var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call

//Constructors With Prototypes

var calculator=function(){
   this.name="Constructors With Prototypes";
};

calculator.prototype.mulFunc=function(num1 ,num2){
 return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call
Sheo Dayal Singh
  • 1,591
  • 19
  • 11
-2

In most cases you have to somehow declare the property you need before you can call a method that passes in this information. If you do not have to initially set a property you can just call a method within the object like so. Probably not the most pretty way of doing this but this still works.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
Coded Container
  • 863
  • 2
  • 12
  • 33