Skip to main content
Ben Nadel at NCDevCon 2011 (Raleigh, NC) with: Garrett Johnson
Ben Nadel at NCDevCon 2011 (Raleigh, NC) with: Garrett Johnson

Providing A Return Value In A JavaScript Constructor

By
Published in Comments (6)

In my post yesterday, on using Base Controllers in AngularJS, I was able to leverage a funky-fresh feature of the JavaScript language: returning explicit values from a Constructor function. Most of the time, Constructor functions either return "this," or they omit the return statement altogether. However, if you do provide an explicit return statement, it may significantly change the reference returned to the calling context.

To explore this, I set up a number of JavaScript constructor functions that each provide a different, explicit return value. The result of the constructor instantiation is then logged to the console:

<!doctype>
<html>
<head>
	<meta charset="utf-8" />
	<title>Providing A Return Value In A JavaScript Constructor</title>
</head>
<body>

	<h1>
		Providing A Return Value In A JavaScript Constructor
	</h1>

	<script type="text/javascript">


		// Undefined return value.
		function A() {
			return;
		}

		// Reference to instance.
		function B() {
			return( this );
		}

		// String return value.
		function C() {
			return( "string" );
		}

		// Number retun value.
		function D() {
			return( 123 );
		}

		// New object return value.
		function E() {
			return( { foo: "bar" } );
		}

		// New array return value.
		function F() {
			return( [ "foo", "bar" ] );
		}

		// New instantiation return value.
		function G() {
			return( new A() );
		}

		// Native "object" return value -- this one would be the same
		// for Number, Boolean, and String.
		function H() {
			return( new Number( 123 ) );
		}


		// -------------------------------------------------- //
		// -------------------------------------------------- //


		// See what reference we have as a result of instantiation.
		console.log( new A() );
		console.log( new B() );
		console.log( new C() );
		console.log( new D() );
		console.log( new E() );
		console.log( new F() );
		console.log( new G() );
		console.log( new H() );


	</script>

</body>
</html>

When I run the above code, I get the following console output:

A {}
B {}
C {}
D {}
Object { foo="bar"}
["foo", "bar"]
A {}
Number {}

As you can see, the first four invocations return the constructor instantiation to the calling context. But, when you start returning explicit, complex objects and arrays in a constructor function, you completely override the reference that is returned to the calling context.

This is an odd feature of the language, but it's not unique; I'm pretty sure that ColdFusion also provides similar behavior. That said, it is a nifty feature of the language that can really do some awesome stuff.

Want to use code from this post? Check out the license.

Reader Comments

1 Comments

I think the basic rule is that if you return an object, that is used. Otherwise, the constructed object is.

15,902 Comments

@Alex,

Correct - this is why a return value of "123" is ignored; but, a return value of Number( 123 ) is used. The latter returns a complex object, not a simple value.

34 Comments

I can possibly see this as a way to create an object that lets you use the "new Something()" syntax as a constructor but allows "private" methods through encapsulation, but what other use-cases would you have?

15,902 Comments

@Jon,

The most recent place that I used this was to create a constructor that was actually a *factory* for a different type of object. Along those lines, I suppose you could use such a pattern to enforce a "singleton". So that no matter what, you only ever return a single, common reference to a given object. Something like:

function Singleton() {
 
	if ( Singleton.instance ) {
		return( Single.instance );
	}
 
	return( Singleton.instance = this );
 
}

This way, no matter how many times you call "new Singleton()", the class always returns the same instance.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel