JavaScript inheritance – experimenting with syntax alternatives and private variables

After my recent posts about JavaScript, there were some people asking for more information about inheritance – intrigued by the concept myself, and also inspired by Andrea Giammarchi’s comment , I though I’d come up with some scary shit. :-)

Prerequisites

Before reading this article, I strongly recommend reading JavaScript inheritance – how and why and Explaining JavaScript scope and closures first, since many phenomenon below will have their explanation there.

Article objective

After this article, there will be no holy grail of how to code inheritance in JavaScript. I will introduce some common ways, touch on their problems and what one might want to achieve. Most of all, it’s a lesson in very different syntaxes for doing the same thing, and opening your to the wonderful and magical JavaScript world. :-)

At the end of the day, though, it’s up to you to choose what you seem best, or just be inspired by the many options you have to code JavaScript.

First inheritance steps

Let’s start with our first inheritance example, look at the code, an then see what’s good respectively not so good with it.

Inheritance from a regular object

I thought we’d start out easy, with inheriting from a regular object:

// Basic object
var Base = {
	
	// Public properties and methods
	dayName : "Tuesday",
	
	day : this.dayName,
	
	getDay : function () {
		return this.dayName;
	},
	
	setDay : function (newDayName) {
		this.dayName = newDayName;
	}
};

Cool so far? Good. Let’s create an object which inherits from our basic Base object:

// Using new Base() is not an option, 
// since it isn't a constructor
Sub.prototype = Base;
function Sub () {
	// Constructor
};

A test run

var a = new Sub();
// Returns "Tuesday"
alert(a.getDay());

var b = new Sub();
// Returns "Tuesday"
alert(b.getDay());

// Sets dayName to "Wednesday"
a.setDay("Wednesday");

// Returns "Wednesday"
alert(a.getDay());

// Returns "Tuesday"
alert(b.getDay());

// Returns undefined
alert(b.day);

Everything above is probably what you expected, except the last one that returned undefined. The problem is that the Base object tries to set a property while it’s executing, and then it doesn’t have any internal reference. Using a method instead for the day property would be a possibility to make it work:

day : function () {
	return this.dayName;
}

What’s good

As mentioned in the comment, you can point out Base object as the ancestor to inherit its prototype from, but since Base isn’t a real constructor, you cannot call it with the new keyword. Basically, this means that the Base constructor isn’t run, until an instance of the Sub object is being created.

This can be a good thing, since you might not want any unnecessary code to be run in the constructor, before it’s actually time. Personally, I never have anything important in the constructor, but put in an init method instead, so I can completely control when it is being invoked.

Not so good

What’s less good here is that all properties and methods are declared inline of the Base object, meaning you can’t utilize the prototype behavior. Also, there’s no way to have any private variables.

Private variables/members and prototype

Something a lot of people ask about is if it’s possible to have private variables in an object, and then being able to access them through any prototype method. The answer is, unfortunately, no (kind of). For private methods, however, there is an opportunity which I will go into later below.

Starting the syntax circus

From here on, I will present three different syntax alternatives to basically achieve the same results, but in very different fashions. It will also show the problems with private variables and prototype, and how it does work with private methods.

Basic Prototype inheritance

First out is regular prototype inheritance, where one private variable and one private method are declared:

// Basic Prototype inheritance
function Base () {

	// Private variable
	var dayName = "Tuesday";
	
	// Private method
	function getPrivateDayName () {
		return dayName;
	}

	// Public properties and methods
	this.day = dayName;

	this.getDay = function () {
		return getPrivateDayName();
	};

	this.setDay = function (newDayName) {
		dayName = newDayName;
	};
};


Sub.prototype = new Base;
function Sub () {
	// Constructor
};

What’s good

Simple syntax and everything reachable from within the constructor.

Not so good

To be able to access the private variable and private method, everything needs to be within the constructor, instead of through prototype assignment. Not a recommendable approach.

Yahoo JavaScript Module Pattern

I’ve mentioned it before, but my personal favorite when it comes to singleton objects is the Yahoo JavaScript Module Pattern. With the prospect of prototype inheritance, you can also use it as the prototype ancestor object for any sub object you are interested in creating. Basically, like this:

// Yahoo JavaScript Module Pattern
var Base = function () {
	
	// Private variable
	var dayName = "Tuesday";
	
	// Private method
	var getPrivateDayName = function () {
		return dayName;
	}
	
	// Public properties and methods
	return {
		
		day : dayName,
		
		getDay : function () {
			return getPrivateDayName.call(this);
		},
		
		setDay : function (newDayName) {
			dayName = newDayName;
		}
	};
}();

// Using new Base() is not an option, 
// since it isn't a constructor
Sub.prototype = Base;
function Sub () {
	// Constructor
};

What’s good

Nice code structure, good separation between private and public properties and methods.

Not so good

It isn’t a “true” constructor, so you can’t call it with new. Also, all public properties and methods are inline in the object, so it can’t utilize the recommended prototype approach.

Closure-created constructor

This piece of code creates a closure where you have the constructor, private variables and methods and assigns prototype properties and methods to the object. It then return the actual constructor object, so the next time it is run it’s behaving just like a normal constructor, while the closure makes sure all methods and values are still accessible.

By far the coolest code, if you ask me. :-)

// Closure-created constructor
var Base = (function () {
	
	// Constructor
	function Base () {
		
	}
	
	// Private variable
	var dayName = "Tuesday";
	
	// Private method
	function getPrivateDayName () {
		return dayName;
	}
	
	// Public properties and methods
	Base.prototype.day = dayName;
	Base.prototype.getDay = function () {
		return getPrivateDayName.call(this);
	};
	
	Base.prototype.setDay = function (newDayName) {
		dayName = newDayName;
	};
	
	return Base;
})();


Sub.prototype = new Base;
function Sub () {
	// Constructor
};

What’s good

This code uses a closure to have a constructor initiated, with complete control over prototype properties and methods, which in turn have access to private variables and methods. Its structure, if you ask me, is very nice, because you have the constructor and the properties and methods within the same code block, giving it more of a togetherness.

Not so good

The only real downside is that the private variable is limited to the scope, hence being the same for all instances. Also, it’s a bit weird to have private variables outside of the constructor.

The code execution results for all three approaches

var a = new Sub();
// Returns "Tuesday"
alert(a.getDay());

var b = new Sub();
// Returns "Tuesday"
alert(b.getDay());

// Sets dayName to "Wednesday"
a.setDay("Wednesday");

// Returns "Wednesday"
alert(a.getDay());

// Returns "Wednesday"
alert(b.getDay());

// Returns "Tuesday"
alert(b.day);

But why? The problem is that the scope each approach uses to create a private variable, which works fine, is also the closure, in action, that results in if you change a private variable for one object instance, it is being changed for all. I.e. it’s more like a private static property, than an actual private variable.

So, if you want to have something private, more like a non-public constant, any of the above approaches is good, but not for actual private variables. Private variables only work really well with singleton objects in JavaScript.

In terms of private methods, however, it works swell! You can hide away helper methods from the public eye, and then utilize it from your prototyped code.

Download the complete code

To make it easier for you, I’ve put all four code approaches in the same JavaScript file, so you can download the inheritance demo JavaScript file and play around with the code, tweak some settings, and hopefully, at the end of the day, be a more enlightened JavaScript programmer. :-)

Wrapping up

As you can see, JavaScript offers many ways to do the same thing with code, and different solutions have different advantages and disadvantages. I also think an important lesson to learn is that there’s a difference between code doing/delivering the expected results and optimal code best for runtime, execution and reusage.

Feedback

Please let me know what you thought of this experiment! I wanted to mess with your heads a little, while also opening up your mind to alternative solutions. If anything’s wrong or or not as good as it can be with the code, or if you have any solutions to the problems posed above, don’t hesitate to let me know!

Posted in Developing,JavaScript,Technology |

Leave a Reply

Your email address will not be published. Required fields are marked *