2

Intro: I start to read Javascript Patterns book and can't grasp one example. It's pretty big so I'll try to explain it briefly before getting you a code.

Examples explanation: So what they try to do is to define singleton with help of Closure. The first piece of code is pretty simple, but it has one significant drawback - we can't redefine prototype after creating the first instance of Universe.

Question: Could someone explain me how does the second example ('Good' singleton) code manage to change prototype after first constructor call?

'Bad' singleton:

function Universe() {
    var instance = this;
    this.start_time = 0; 
    this.bang = "Big";
    Universe = function () {
        return instance; 
    };
}
// testing
Universe.prototype.nothing = true;
var uni = new Universe();
Universe.prototype.everything = true;
var uni2 = new Universe();
uni.nothing; // true 
uni2.nothing; // true 
//AS YOU CAN SEE ALL CHANGES TO UNIVERSE PROTOTYPE HAVE NO RESULT AFTER FIRST CONSTRUCTOR CALL
uni.everything; // undefined 
uni2.everything; // undefined

And then they solve the problem with code below:

'Good' singleton:

function Universe() {
    var instance;
    Universe = function Universe() {
       return instance; 
    };
    Universe.prototype = this;
    instance = new Universe();
    instance.constructor = Universe;
    instance.start_time = 0; 
    instance.bang = "Big";
    return instance; 
}
// testing
Universe.prototype.nothing = true;
var uni = new Universe();
//QUESTION: how does it manage to change the prototype of singleton?!
Universe.prototype.everything = true;
var uni2 = new Universe();
uni.nothing && uni.everything && uni2.nothing && uni2.everything; // true

The same question in other words: why in the first code snippet uni.everything == false and uni2.everything == false but in the second one uni.everything == true and uni2.everything == true? As for me, they should be false in both cases

2
  • Of course it is, it's always returning the instance created the first time. Commented Sep 19, 2014 at 9:45
  • @Qantas94Heavy which question have you just answered? Commented Sep 19, 2014 at 9:46

1 Answer 1

4

Note: please feel free to reword this answer to make it sound better, I probably haven't explained it well.

Example 1 ("Bad" singleton)

In your first example:

function Universe() {
    var instance = this;
    this.start_time = 0; 
    this.bang = "Big";
    Universe = function () {
        return instance; 
    };
}

When you call new Universe() the second time, it returns the instance stored from the first time (when the global Universe constructor was replaced), not a new object. This is why any changes to Universe.prototype have no effect.

Example 2 ("Good" singleton)

Your second example is a bit more complicated. The first time you call it, this refers to the object initially created, which means it has the prototype with the nothing property. As this object is now the prototype for the instance returned, the nothing property is inherited.

Because now when you call new Universe() a second time it is returning the result of instance = new Universe() from the first time, any changes to it are also kept with it.

Because you returned instance in the original Universe function, uni is the same object as uni2.

This would have the same effect as doing this:

var Universe2;

function Universe() {
    Universe2 = function () {
         return instance; 
    };
    Universe2.prototype = this;
    var instance = new Universe2();
    instance.constructor = Universe2;
    instance.start_time = 0; 
    instance.bang = "Big";
    return instance;
}

Universe.prototype.nothing = true;

var uni = new Universe();

Universe2.prototype.everything = true;

var uni2 = new Universe2();

And then the final object would look like this:

==========================
= Object.prototype       =
=  - hasOwnProperty: ... =
=  - toString: ...       =
=  - ...                 =
==========================
            ^
            |
            |
            |
            |
==========================
= Universe.prototype:    =
=   - nothing: true      =
==========================
            ^
            |
            |
            |
            |
==========================
= Instance of Universe:  =
=  - everything: true    =
==========================
            ^
            |
            |
            |
            |
==========================
= Instance of Universe2: =
=  - start_time: 0       =
=  - bang: "Big"         =
==========================
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.