473,390 Members | 1,273 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,390 software developers and data experts.

Singleton in JavaScript

Hi,

A lot of functions (classes) in my JavaScript app are singletons. So, I have
been exploring ways making JavaScript functions singletons. I thought I'ld
run one idea past you all and get some feed back.

The usual method of making singletons is to have a static member that
returns one instance of the class. But, JavaScript has no notion of static.
The closest it has is prototype functions.

// The singleton class
function Single() {
// call the "static" GetInstance()
return Single.prototype.GetInstance();
}

// The only instance.
Single.prototype._single = null;

// static function
Single.prototype.GetInstance = function() {
if( !Single.prototype._single ) {
Single.prototype._single = this;
}
return Single.prototype._single;
}
----------

So, "new Single() == new Single()" is true.
Or "new Single() == Single.prototype.GetInstance()"

What do you all think? Is the "new Single()" going to be confusing? Is there
are way to do "Single.GetInstance()"? I think the prototype version is
unweildy.

-------------------------------------------------------------

When can I refer to prototype functions or prototypes full stop? It appears
that "this.GetInstance" exists in "new Single()", but I can't call it.

JohnS
Jul 20 '05 #1
10 8266
"JohnS" <js*************@optusnet.com.au> wrote in message
news:3f***********************@news.optusnet.com.a u...
<snip>
... . But, JavaScript has no notion of static.
The closest it has is prototype functions. <snip>

In JavaScript public static members are created a properties of the
function object that represents the constructor:-

function Single() {
if(!Single.instance){
//construct objectc
Single.instance = this;
}
return Single.instance;
}

Single.instance = null; //public static member

- and private static members may be emulated by forming a closure with
the constructor:-

var Single = (function(){
var instance = null; //private static member
return (function(){ //return the constructor function
if(!instance){
//construct object
instance = this;
}
return instance;
});
})(); //inline execution of anonymous function

- (or the prototype, but it is cleaner and more flexible with the
constructor).
... Is there
are way to do "Single.GetInstance()"?

<snip>

Yes, public static methods are completely normal:-

Single.GetInstance = function(){
. . . //function body
}

Richard.
Jul 20 '05 #2

That's great. So, I can drop the prototype and just put GetInstance straight
into the function. I didn't know that.

The second example threw me for a bit. It seemed like it should return a
typeof "function" . But, it returns a typeof "object". So, it's contructing
an object without using the "new" keyword. Strange.

It seems to mean, that when you call a straight function, the function
becomes an object and then executes. If you return "this", you have a
function instance/object.

Also, if you have an inner function, "this" refers to the outer "this".

Thanks for your help.

JohnS

----- Original Message -----
From: "Richard Cornford" <Ri*****@litotes.demon.co.uk>
Newsgroups: comp.lang.javascript
Sent: Thursday, August 21, 2003 6:01 PM
Subject: Re: Singleton in JavaScript

"JohnS" <js*************@optusnet.com.au> wrote in message
news:3f***********************@news.optusnet.com.a u...
<snip>
... . But, JavaScript has no notion of static.
The closest it has is prototype functions.

<snip>

In JavaScript public static members are created a properties of the
function object that represents the constructor:-

function Single() {
if(!Single.instance){
//construct objectc
Single.instance = this;
}
return Single.instance;
}

Single.instance = null; //public static member

- and private static members may be emulated by forming a closure with
the constructor:-

var Single = (function(){
var instance = null; //private static member
return (function(){ //return the constructor function
if(!instance){
//construct object
instance = this;
}
return instance;
});
})(); //inline execution of anonymous function

- (or the prototype, but it is cleaner and more flexible with the
constructor).
... Is there
are way to do "Single.GetInstance()"?

<snip>

Yes, public static methods are completely normal:-

Single.GetInstance = function(){
. . . //function body
}

Richard.

Jul 20 '05 #3
Hi, I just wanted to add a tiny thing that I'm not sure was mentioned.
Another way of declaring a static function is:

function Single.GetInstance() {
....
}

This way your call stack will have a named function instead of an
anonymous one.

"Richard Cornford" <Ri*****@litotes.demon.co.uk> wrote in message news:<bi*******************@news.demon.co.uk>...

Single.GetInstance = function(){
. . . //function body
}

Richard.

Jul 20 '05 #4
b0*****@yahoo.com (asdf asdf) writes:
Hi, I just wanted to add a tiny thing that I'm not sure was mentioned.
Another way of declaring a static function is:

function Single.GetInstance() {
...
}
Not in ECMAScript v3 or any Javascript I have seen. It doesn't appear
to work in JScript.NET (which implements the proposed ECMAScript v4).

It is just a syntax error. It would be very nice is that syntax was
supported, but it isn't.
This way your call stack will have a named function instead of an
anonymous one.


You could write either

function getInstance() {...}
Single.GetInstance = getInstance;

or

Single.GetInstacne = function GetInstance() {...}

Just remember that there is no difference between a "named" function
and an anonymous one. It is just a function object, which is an anonymous
value, that has been assigned to a variable.

/L 'please don't top post'.
--
Lasse Reichstein Nielsen - lr*@hotpop.com
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #5
"JohnS" <js*************@optusnet.com.au> wrote in message
news:3f***********************@news.optusnet.com.a u...
<snip>
The second example threw me for a bit. It seemed like it should
return a typeof "function" . But, it returns a typeof "object".
So, it's contructing an object without using the "new" keyword.
Strange.
When you say 'it returns a typeof "object"', what do you men by "it".
Single should be a reference to a function (the constructor returned by
the incline function expression call), as a constructor, calling - new
Single(); - will return an object. A new object the first time it is
called and that same object on every subsequent call. However, if you
call any custom JavaScript constructor without using the - new - keyword
you will not get a new object constructed and there is every chance that
the function will execute as global code and the - this - keyword will
refer to the global object.
It seems to mean, that when you call a straight function, the
function becomes an object and then executes. If you return
"this", you have a function instance/object.
If you call a global function the - this - keyword will refer to the
global object, if - this - is returned then the object returned will be
the global object.
Also, if you have an inner function, "this" refers to the
outer "this".


No it will not. For inner functions - this - could be one of may
objects. If the inner function is assigned as a method of an object
(including function objects) then - this - refers to that object, else
an inner function - this - will be the global object unless that inner
function is called as a constructor using the - new - keyword, in which
case - this - refers to the new object. The specifics are described in
the ECMA Script specification.

Richard.
Jul 20 '05 #6
Single is a reference to a function. But calling Single(), returns an
object. In fact, Single() == new Single(), always.

I now understand why I was confused. When calling Single(), the instance
variable was inited with the global this. Arghh!
So, you are right, you need the new keyword to get a new this. But, after
the first call of new Single(), you can call Single() to get
the instance.

I think I'll change the constructor to create a new Single() if this is
global.

Thanks for your explainations.

----------------------------------------------------------------------------
-------
Here the the test code I used:
note: If you call Single() before new Single(), isObjectGlobal() returns
true.
function p( msg ) {
document.write( msg + "<BR>" );
}

var gThis = this;
function isObjectGlobalThis( myThis ) {
return myThis == gThis;
}

// Singleton
var Single = (function(){
var instance = null; //private static member
return (function(){ //return the constructor function
if(!instance){
//construct object
p( "Constructing this" );
instance = this;
}
p( "Returning this" );
return instance;
});
})(); //inline execution of anonymous function
function test() {

p( "Calling new Single()" );
single1 = new Single();
p( "" );

p( "Calling Single()" );
single2 = Single();
p( "" );
p( "typeof Single: " + typeof Single );
p( "typeof Single(): " + typeof single1 );
p( "typeof new Single(): " + typeof single2 );
p( "" );

p( "Single() == new Single(): " + (single1 == single2) );
p( "" );

p( "isObjectGlobalThis( test ): " + isObjectGlobalThis( this ) );

p( "isObjectGlobalThis( Single() ): " + isObjectGlobalThis( single1 ) );
p( "isObjectGlobalThis( new Single() ): " + isObjectGlobalThis(
single2 ) );
}

--------------------------------------------------------------------------
Output is:
Calling new Single()
Constructing this
Returning this

Calling Single()
Returning this

typeof Single: function
typeof Single(): object
typeof new Single(): object

Single() == new Single(): true

isObjectGlobalThis( test ): true
isObjectGlobalThis( Single() ): false
isObjectGlobalThis( new Single() ): false
"Richard Cornford" <Ri*****@litotes.demon.co.uk> wrote in message
news:bi*******************@news.demon.co.uk...
"JohnS" <js*************@optusnet.com.au> wrote in message
news:3f***********************@news.optusnet.com.a u...
<snip>
The second example threw me for a bit. It seemed like it should
return a typeof "function" . But, it returns a typeof "object".
So, it's contructing an object without using the "new" keyword.
Strange.


When you say 'it returns a typeof "object"', what do you men by "it".
Single should be a reference to a function (the constructor returned by
the incline function expression call), as a constructor, calling - new
Single(); - will return an object. A new object the first time it is
called and that same object on every subsequent call. However, if you
call any custom JavaScript constructor without using the - new - keyword
you will not get a new object constructed and there is every chance that
the function will execute as global code and the - this - keyword will
refer to the global object.
It seems to mean, that when you call a straight function, the
function becomes an object and then executes. If you return
"this", you have a function instance/object.


If you call a global function the - this - keyword will refer to the
global object, if - this - is returned then the object returned will be
the global object.
Also, if you have an inner function, "this" refers to the
outer "this".


No it will not. For inner functions - this - could be one of may
objects. If the inner function is assigned as a method of an object
(including function objects) then - this - refers to that object, else
an inner function - this - will be the global object unless that inner
function is called as a constructor using the - new - keyword, in which
case - this - refers to the new object. The specifics are described in
the ECMA Script specification.

Richard.

Jul 20 '05 #7
"JohnS" <js*************@optusnet.com.au> wrote in message
news:3f***********************@news.optusnet.com.a u...
Single is a reference to a function. But calling Single(),
returns an object. In fact, Single() == new Single(), always.
As I wrote the Single class it was intended that all calls to it use
the - new - keyword.
I now understand why I was confused. When calling Single(),
the instance variable was inited with the global this. Arghh!
So, you are right, you need the new keyword to get a new this.
But, after the first call of new Single(), you can call
Single() to get the instance.
If you can guarantee that the first call uses - new - and that all calls
that do not use - new - happen after that initial call then you probably
do not want a class at all. Maybe one object assigned to a global
property will do the job sufficiently:-

var Single = {
prop1:1,
prop2:"anyString",
getProp1:function(){
return this.prop1;
},
setProp1:function(x){
this.prop1 = x;
},
getProp2:function(){
return prop2;
}
}

- so all code could just refer to the same object by the identifier
Single.
I think I'll change the constructor to create a new Single()
if this is global.

<snip>

You could do that but you would need a reliable test for the global
object and that would be extra work. If you just want to call a
function - Single() - (without the - new - keyword) and have it always
return the same (non-global) object then there are many aproaches, for
example:-

var Single = (function(){
var instance = null;
function InnerSingle(){
//actual constructor.
this.X = "something";
... //constructor function body
}
InnerSingle.prototype.getX = function(){
return this.X; //example method;
}
return (function(){
if(!instance){
instance = new InnerSingle();
}
return instance;
})
})();

called as - var obj = Single();

- here the real class is the InnerSingle class, whose constructor is
private (inaccessible outside the closure). The rest is just a wrapper
to make acquiring a reference to the one instance convenient. There are
probably at lest another half a dozen ways of achieving the same, using
object literal within the closure, for example:-

var Single = (function(){
var instance = null;
return (function(){
if(!instance){
instance = {
X:"something",
getX:function(){
return this.X;
}
};
}
return instance;
})
})();

-or-

var Single = (function(){
var instance = {
X:"something",
getX:function(){
return this.X;
}
};
return (funciton(){
return instance;
})
})();

called as - var obj = Single();

Alternatively you could return to your original public static -
getInstance - approach. In JavaScript you cannot have a "class" without
a public constructor, while a singleton probably should not have a
public constructor. However, a similar approach as used above could
emulate a class with a public static getInstance method but no
constructor. In this case the - Single - object is not a function (so it
cannot be called as a constructor), instead it is an object with one
public method:-

var Single = (function(){
var instance = null;
function InnerSingle(){
//actual constructor.
this.X = "something";
... //constructor function body
}
InnerSingle.prototype.getX = function(){
return this.X; //example method;
}
return ({
getInstance:function(){
if(!instance){
instance = new InnerSingle();
}
return instance;
}
});
})();

called as - var obj = Single.getInstance();

- the outward appearance and behaviour is that of a class without a
public constructor but with a public static - getInstace - method.

A similar structure could also be used to implement a class with no
public constructor and a factory method that returned a unique new
object on each invocation.

Richard.
Jul 20 '05 #8
Hi -- I believe it works in IE6, which is all I code against. Thanks,
Ron

b0*****@yahoo.com (asdf asdf) wrote in message news:<6f**************************@posting.google. com>...
Hi, I just wanted to add a tiny thing that I'm not sure was mentioned.
Another way of declaring a static function is:

function Single.GetInstance() {
...
}

This way your call stack will have a named function instead of an
anonymous one.

Jul 20 '05 #9
b0*****@yahoo.com (asdf asdf) writes:
Hi -- I believe it works in IE6, which is all I code against.


You are actually right.

function x(){}
function x.y (){alert('foo');}
x.y(); // alerts "foo"

It is important that x is a function. It doesn't work if it is just a
normal object (which was what I first tried).

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
Art D'HTML: <URL:http://www.infimum.dk/HTML/randomArtSplit.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #10
"Lasse Reichstein Nielsen" <lr*@hotpop.com> wrote in message
news:oe**********@hotpop.com...
<snip>
function x(){}
function x.y (){alert('foo');}
x.y(); // alerts "foo"

It is important that x is a function. It doesn't work if it is
just a normal object (which was what I first tried).


It appears that it can work with at leas some objects on IE. I have
seen:-

function window.onload(){
. . . //function body
}

- for example, as a way of defining an onload handler.

But as ECMA Script defines methods for achieving the same effect (that
work on IE) it does not seem like a good idea to be using a syntax that
is not part of the specification even when authoring for exclusively IE.
It would just be another bad habit that would need to be un-learnt prior
to successfully writing cross-browser code.

Richard.
Jul 20 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Phil Powell | last post by:
Consider this: class ActionHandler { ...
1
by: Richard A. DeVenezia | last post by:
foo() generates elements with event handlers that invoke foo function properties. Is this an abhorrent or misthought pattern ? It allows just the one occurence of identifier /foo/ to be changed...
10
by: E. Robert Tisdale | last post by:
Could somebody please help me with the definition of a singleton? > cat singleton.cc class { private: // representation int A; int B; public: //functions
3
by: Alicia Roberts | last post by:
Hello everyone, I have been researching the Singleton Pattern. Since the singleton pattern uses a private constructor which in turn reduces extendability, if you make the Singleton Polymorphic...
3
by: Harry | last post by:
Hi ppl I have a doubt on singleton class. I am writing a program below class singleton { private: singleton(){}; public: //way 1
2
by: Kevin Newman | last post by:
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...
2
by: -Lost | last post by:
Somehow I got lost in an article that led me here: http://www.javascriptkata.com/2007/04/04/how-to-make-a-singleton/ Having recently seen someone else mentioning a Singleton pattern in...
3
weaknessforcats
by: weaknessforcats | last post by:
Design Pattern: The Singleton Overview Use the Singleton Design Pattern when you want to have only one instance of a class. This single instance must have a single global point of access. That...
29
by: Ugo | last post by:
Hi guys, how do you make a singleton access class? Do you know a better way of this one: var singletonClass = (function( ) { // Private variable var instance = null;
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.