By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,127 Members | 1,343 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,127 IT Pros & Developers. It's quick & easy.

A Singleton with Inheritance

P: n/a
I have been playing around with a couple of ways to add inheritance to a
JavaScript singleton pattern. As far as I'm aware, using an anonymous
constructor to create a singleton does not allow any kind of inheritance:

singletonObj = new function() {
this.prop = true;
}

Here are two ways to create a singleton with inheritance:

// class to inherit from
SuperClass = function() {
this.superProp = true;
}

// first way
with ({
SingletonClass: function() {
this.prop = true;
}
}) {
SingletonClass.prototype = new SuperClass();
singletonObj = new SingletonClass();
}

// second way
singletonObj = (function() {
function SingletonClass() {
this.prop = true;
}
SingletonClass.prototype = new SuperClass();
return new SingletonClass();
})();
These also allow you to add prototype based methods and properties to
the Singleton Class (I'm not sure what the benefits and drawbacks of
that are vs just creating the methods and properties within the
constructor - especially since it's a singleton and will only be
instantiated once).

There may be a bunch of better ways to achieve that, but I found it
useful, so I thought I'd share. :-)

Kevin N.

Dec 8 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Kevin Newman <Ca******@unFocus.com> writes:
I have been playing around with a couple of ways to add inheritance to
a JavaScript singleton pattern.
Does the singleton (anti-)pattern make sense at all in a prototype based
language.

In a class based language, a singleton is a type for which there is
only ever one value, i.e., a non-inheritable class with only one
instance.

In a prototype based language, there are no classes and no
corresponding type. Any object can be used as a prototype,
so the singleton behavior cannot be enforced.
As far as I'm aware, using an anonymous constructor to create a
singleton does not allow any kind of inheritance:

singletonObj = new function() {
this.prop = true;
}
While this creates an object with a prototype different from
Object.prototype, there isn't really any advantage over just
doing
singletonObj = { prop:true };
Here are two ways to create a singleton with inheritance:

// class to inherit from
SuperClass = function() {
this.superProp = true;
}
So we restrict ourselves to constructors that can be seen as
representatives of the instances they create, i.e., as pseudo classes.
// second way .... both ways work the same, just using different scoping mechanisms ...
singletonObj = (function() {
function SingletonClass() {
this.prop = true;
}
SingletonClass.prototype = new SuperClass();
return new SingletonClass();
})();


Here the singletonObj uses an instance of SuperClass as its prototype.

Notice that this is not similar to class based inheritance, where
you inherit from the class. It is prototype based inheritance,
where you inherit from a specific instance.

Again I fail to see the advantage over
singletonObj = new SuperClass();
All that happens is that one extra object is put into the
prototype chain.
It is impossible to enforce the singleton pattern, since you can
always create a object inheriting from the existing one:

function clone(o) {
function dummy(){};
dummpy.prototype = o;
return new dummy();
}

notSoSingletonObj = clone(singletonObj);
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Dec 9 '05 #2

P: n/a
Lasse Reichstein Nielsen wrote:
Kevin Newman <Ca******@unFocus.com> writes:
I have been playing around with a couple of ways to add inheritance to
a JavaScript singleton pattern.
Does the singleton (anti-)pattern make sense at all in a prototype based
language.


Reading the rest of your response, I would question whether it does :-)
However, I would argue that creating an object with methods to be
invoked (something reasonably like a singleton), rather than creating an
function (something like a class) to be instantiated, might help someone
who uses my code to understand how I intended them to use it, though I
guess there is nothing like good documentation.

In a class based language, a singleton is a type for which there is
only ever one value, i.e., a non-inheritable class with only one
instance.
Hmm.. I guess some patterns just do not apply to JavaScript then. Maybe
this should be described as something other than a Singleton, but it may
still be useful. I am using it to discourage (since as you have pointed
out, I cannot completely stop) re-instantiation, or inheriting from,
since in my real life implementation the object will be setting up some
resource hungry processes (like an interval function that we wouldn't
want to create more than one of). I wonder if there is a better way to
achieve that though (again, maybe it's just good documentation).

In a prototype based language, there are no classes and no
corresponding type. Any object can be used as a prototype,
so the singleton behavior cannot be enforced.
As far as I'm aware, using an anonymous constructor to create a
singleton does not allow any kind of inheritance:

singletonObj = new function() {
this.prop = true;
}
While this creates an object with a prototype different from
Object.prototype, there isn't really any advantage over just
doing
singletonObj = { prop:true };


In my example there is no advantage. I should have included some
privileged variables, or set up a setInterval function, to demonstrate
why I have used this (non-)pattern I suppose. I'll have to do some
thinking on this..
Here are two ways to create a singleton with inheritance:

// class to inherit from
SuperClass = function() {
this.superProp = true;
}
So we restrict ourselves to constructors that can be seen as
representatives of the instances they create, i.e., as pseudo classes.
// second way

... both ways work the same, just using different scoping mechanisms ...
singletonObj = (function() {
function SingletonClass() {
this.prop = true;
}
SingletonClass.prototype = new SuperClass();
return new SingletonClass();
})();


Here the singletonObj uses an instance of SuperClass as its prototype.

Notice that this is not similar to class based inheritance, where
you inherit from the class. It is prototype based inheritance,
where you inherit from a specific instance.

Again I fail to see the advantage over
singletonObj = new SuperClass();
All that happens is that one extra object is put into the
prototype chain.
It is impossible to enforce the singleton pattern, since you can
always create a object inheriting from the existing one:

function clone(o) {
function dummy(){};
dummpy.prototype = o;
return new dummy();
}

notSoSingletonObj = clone(singletonObj);


Well that's a good point. I hadn't considered that. :-) I guess with a
language as flexible as JavaScript, discipline is the only solution to
prevent re-instantiation.

At the more abstract level, I would argue that your method for cloning
the (non-)singleton is pretty advanced, and that creating an
instantiated object in the global space, instead of a function that a
user must instantiate only once, could be useful to help prevent novice
JavaScript users from re-using a "class" that they should really only
have one instance of.

I guess I could consider a different architecture for my app - maybe one
where the object that the user is instructed to use (by the
documentation), would utilize something like a singleton on it's own,
and make sure that the resource are not duplicated, even with
reinstantiation.
/L


Well anyway, thanks for the reply. I always learn something, and I
appreciate it.

Kevin N.

Dec 9 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.