Recently while I was speaking with a fellow programmer, he was telling me how he wished that javascript had private methods/variables… sometimes it just felt so dirty just going on the honor system using “intended private” variables, i.e.

function Foo(){
    this._value = null;
}

I thought it was possible to have private variables and methods, and after some toying around I discovered I was right. The trick is to create local variables inside your “constructor”, then declare instance methods to access them (methods added to the object prototype can’t access them).

So, say we want a Person object who’s name is private, but provide getters/setters for it:

function Person(){
	var name;

	this.getName = function(){return name;}
	this.setName = function(n){name = n};
}
// EXAMPLE
var dude = new Person();
dude.setName('The Dude');
alert(dude.getName()); // prints "The Dude"

These methods are known as privileged methods… they can access private items and may be invoked publicly, however they may not be modified. Using the above defined object, if I do this:

var dude = new Person();
dude.setName = function(f){//.. some crud ...//}

Um.. nothing happens… calling dude.setName(”The Dude”); still uses the original. But out of curiosity, I added a method with the same name to the prototype and it still called the original. But the new method is there, how the hell do I call it!?

Person.prototype.setName = function(name){ alert("test");}
dude.setName('The Dude'); // calls the original method
Person.prototype.setName.call(dude, 'ffff'); // alerts "test"

Interesting, although haphazard. I think we will leave it at that. ;)

Private methods work the same way… by declaring them as local variables in the “constructor” and then accessing them through instance methods declared there as well. Methods added to the prototype cannot access them.

So, to recap:

function House(r){
	var rooms = r;
	this.location = "downtown";
	var getNumberOfDoors = function(){
		return rooms*2; // each room has 2 doors.
	}
	this.information = function(){
		return "This house has " + rooms + " rooms and a total of " + getNumberOfDoors() + " doors.";
	}
}
House.prototype.getRooms = function(){
	return this.rooms;
}
House.prototype.getRooms2 = function(){
	return rooms;
}

var house = new House(5);
alert(house.information()); // prints "This house has 5 rooms and a total of 10 doors."
alert(house.location); // prints downtown
alert(house.getRooms()); // prints undefined
alert(house.rooms); // prints undefined
alert(house.getRooms2()); // breaks, no such variable

If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!