Wednesday, August 06, 2008

JavaScript: Constructor Return Value

What happens when a constructor returns a value?

A constructor in JavaScript is any function which handles being called using the new operator. What happens is a blank Object is instantiated and accessible to said method via a this reference. Two things a constructor will typically do is assign a prototype and add instance-based members. However, you constructors can return values to manipulate what object the caller receives using the return value!

If a constructor function returns nothing, null, or any atomic / non-object value then said value is ignored and the newly created object reference is given back to the caller. For example, a return value of 0 (zero) from a constructor function will be ignored.
function Deebee() { return 0; }
var db = new Deebee();
if (!db)
  throw Error("JS constructor returned non-object!");
The second piece of magic eluded to above is the ability for a constructor to return a specific, possibly pre-existing object, rather than a reference to a new instance. This would allow you to manage the number of actual instances yourself if needed; possibly for reasons of limited resources or whatnot.
var g_deebee = new Deebee();
function Deebee() { return g_deebee; }
var db1 = new Deebee();
var db2 = new Deebee();
if (db1 != db2)
  throw Error("JS constructor returned wrong object!");
Unfortunately there are no inherent destructors in JavaScript, no way to be called when an object is out of scope and about to be garbage collected. Typically the way to get around this is to write more procedurally when working with scripts controling finite resources, e.g. explicitely call some close/destroy/quit/end/etc. function after you're finished. This is another reason you might opt to share object references so your script can keep track and not exceed any limits which would cause exceptions.

Finally, remember that instead of using a global variable, you can store references on the function object itself. I recommend it to better compartmentalize the logic under a single entry in the global namespace, and so it's not actually executed until needed.
function Deebee()
{
  if (undefined == Deebee.o)
    Deebee.o = this;
  return Deebee.o;
}
Check out the full-script example: [ex-constructor-return.js]. You can run this in Windows from a command prompt by typing:
cscript.exe ex-constructor-return.js
Or try it in your web browser by putting it in a HTML document:
<pre> <script language="JavaScript" src="ex-constructor-return.js" > </pre>
Constructor magic! Please post additional tips/tricks or questions as comments.

4 comments:

Anonymous said...

thx, helped me a lot

Anonymous said...

Thanks. Good description.

Anonymous said...

``if (undefined == Deebee.o)´´

So, Yoda comparisons, you like?

Juan Mendes said...

I think a Factory constructor is a clearer way to manage a pool of resources. To me a constructor should always return a new object.