1
\$\begingroup\$

I am diving deeper into JavaScript and starting to learn more about prototypes and simulating classes etc. I am used to working with the Module pattern and would like to try and combine this pattern along with working with prototyping into an own little framework (purely for learning purposes).

I have devised a little construct and I was hoping if some of you advanced users could give me some feedback on the particular construct.

What I am trying to achieve is to create a singleton with methods and properties one could access, I would like to extend/build this via the prototype as speed is something I care a lot about. The thing I still have doubts about is whether or not this would be a suitable construct for what I have in mind, whether or not this would be fast etc.

Much appreciated! Here's the code.

var Mui = (function (window, document, undefined) {

Mui = function () {
    this.Version = {
        Major  : '0',
        Minor  : '1',
        Bugfix : '0'
    };
};

Mui.prototype = {
    sayHi : function () {
        alert('hi');
    }
};

return new Mui;

}(window, this.document));
\$\endgroup\$
  • \$\begingroup\$ So, you want the Version property to be hard-coded into the Mui constructor, yes? \$\endgroup\$ – Šime Vidas Feb 24 '12 at 21:16
  • \$\begingroup\$ @Šime Vidas Not really, to be honest i added it so the constructor wouldn't be empty. I would assume i want to update the numbers more dynamicly. \$\endgroup\$ – ngr Feb 24 '12 at 21:21
2
\$\begingroup\$

A singleton is an object which is the only instance of its type. Therefore, it makes most sense to define all non-function properties and methods directly on that singleton:

var singleton = {
    prop1: ...,
    prop2: ...,
    method1: function () { ... },
    method2: function () { ... }
};

Extending the singleton is easy:

singleton.prop3 = ...;
singleton.method3 = ...;  
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

If you want you constructor function to be a singleton, you are going to have to make a few tweaks to your code:

var Mui = function () {
    //the cached instance
    var instance;

    //rewrite the constructor
    Mui = function Mui() {
        return instance;
    };

    //carry over the prototype properties
    Mui.prototype = this;

    //the instance
    instance = new Mui();

    //reset the constructor pointer
    instance.constructor = Mui;

    //all the functionality
    instance.version = {
        Major  : '0',
        Minor  : '1',
        Bugfix : '0'
    };
    return instance;
};

Mui.prototype.sayHi = function() {
    alert('Hi');
};

var mui_1 = new Mui();
var mui_2 = new Mui();
alert(mui_1 === mui_2); //true​

You can see this working here: http://jsfiddle.net/34vCH/3/

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ He returns new Mui from his closure; you can't get at the Mui constructor without removing the closure as you've done here. It was a valid singleton object. There's really no reason for the constructor to be a singleton; usually "singleton" in prototype-oo-speak refers to an object rather than a function. \$\endgroup\$ – Dagg Feb 24 '12 at 22:16
  • \$\begingroup\$ @GGG, you can do this with a closure but I don't care for the implementation. I agree that 99% of the time you should just use an object literal for a singleton. Because that was already an answer and the questions involved a constructor function I decided to show an alternative solution. \$\endgroup\$ – Paul Feb 24 '12 at 23:07
1
\$\begingroup\$

I agree with Šime Vidas; simplicity is best here.

var mui = {

    version: {
        major  : '0',
        minor  : '1',
        bugfix : '0'
    },

    sayHi : function () {
        alert('hi');
    }

};

There is no reason to use a constructor, since it will only construct a single object. Best to create the object directly.

On a side note, don't use this to refer to the global object. document would work just as well as this.document.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Simplicity is good i agree. Because i define the MUI just once there will be no benefits by declaring the methods/properties on the constructors prototype? I am refering to speed wise etc. \$\endgroup\$ – ngr Feb 24 '12 at 22:28
  • \$\begingroup\$ You could always run performance tests to see exactly how big of a difference it makes, but creating a single object directly will always be faster than creating a function to invoke to create that object. The performance difference is probably negligible since the object is only created once, but doesn't this code look cleaner and easier to understand? That's the main advantage I think. \$\endgroup\$ – Dagg Feb 24 '12 at 22:40
  • \$\begingroup\$ Some browsers might also take longer to search the prototype chain for the functions in your example. In this example the functions are properties of the object itself, in your example they are properties of the object's prototype. \$\endgroup\$ – Dagg Feb 25 '12 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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