Javascript variable scope, private protected and public
Javascript is a tricky language. Since I learned programming with Java, I always find myself trying to find its equivalence in other languages I come across.
I know its bad in that in that it kind of stops me from exploring the potentials provided by other languages in full. Its like going to a Chinese restaurant and eating fried rice everytime because fried rice is the only dish that is close to what I’m used to eating daily.
There’s such variety in Chinese food, and yet if I go there and I eat fried-rice evertyime Its a sign I have a bit of a problem opening myself up to new things. And that’s a big problem.
The world has such diversity in every-aspect imaginable, ( with the exception of mob-justice and mob-mentality which seem to cross all cultural and geographical boundary as it seems), and not being able to appreciate the diversity and learn for it is a great pity.
Back to programming, not all constructs found in languages are sole property of a given language. They are generally abstractions provided by languages to solve problems effectively and those abstractions can be applied in other languages even if they don’t provide such explicit constructs.
There was a time when I treated javascript like lepers, something to avoid at all cost, except when it was really unavoidable.
But then I had a change of perspective, at a philosophical level -dare I day. ‘If I avoid something to such length then I must be shit-scared of it for some reason’.
And by nature I hate to admit my fears for the fear of being tagged a wussy, a chicken.
Of course I can find things to justify my avoidance of javascript to others without admitting my fear, but how about myself?
What do I tell myself when I go to sleep??
And since I couldn’t find reasonable arguments to fool myself into good sleep because my rational self always counter-argued that ‘you fear what you don’t understand’, and my arguments against javascript were just my lame attempt to hide my fears , I decided to deal with my fears for once and for good.
And since then I have been quite happy with my javascript experience.
Since I’m still a Java fan-boy, though I have a feeling that it won’t be for too long, Scala! here I come, I tried to find solution to variable scoping in javascript so that I have more control over objects I create and the API’s I expose. This has been a big issue due to the need for me to use at least 3-4 third-party libraries to get my job done for the current project I’m rewriting.
And the project has a massive javascript code-base.
Looking back at the code I did last year makes me cringe. There was no modularity and there was too much interdependency between components and objects.
(Hmm… component decoupling is entirely another topic for another sleepless night.)
And this time around I decided to do thing the right way – at least to my best knowledge.
After long hours prowling the internet, finally I managed to understand the trick to accomplish what I wanted.
So here’s an example of an object with everything pubic, the dumbest example.
var Person= function(name ,surname, sex, dob){
this.name=name;
this.surname=surname;
this.sex=sex;
this.dob=dob;
this.getFullName=function(){
return this.surname+","+this.name;
}
this.getAge=function(){
return (new Date().getYear() - this.dob.getYear()) ) ;// I'm being lazy here
}
}
// another a little less dumb-looking flavor with prototyping but dumb nonetheless
var Person= function(name ,surname, sex, dob){
this.name=name;
this.surname=surname;
this.sex=sex;
this.dob=dob;
}
Person.prototype.getFullName=function(){
return this.surname+","+this.name;
}
Person.prototype.getAge=function(){
return (new Date().getYear() - this.dob.getYear()) ) ;
}
All the properties in of the object are accessible to any function/code that instantiates Person object. And getFullName() is nothing more but a handy method for getting both name and surname.
And the calling code can access dob and compute age by itself.
So everything is accessible.
var person = new Person('inny', 'minny', 'yes please', new Date(1901, 0, 1) );
var fullname= person.surname+","+person.name;
var age= (new Date().getYear() - person .dob.getYear()) ) ;
Of course one can argue that we can differentiate the difference between private and public by using underscore for private properties such as _dob ( as a lot of people insist on doing).
But who are we fooling? That’s just a convention we use, and if you work in a large team there’s no guarantee that someone else will not get smart and start mutating the underscored variable and shit might hit the fan depending on how critical the property is.
Instead of developing ad-hoc convention I believe its more ideal to use the best of what a language provides without having to define our own rule which can be broken by anyone who cares to break it. Sometimes I don’t trust myself,let alone trust others.
So if we need to hide the DOB for privacy reason and only expose the age, and we need to hide the individual name and surname for some reason, here’s how its done:
var Person= function(name ,surname, sex, dob){
this.sex=sex;
this.getFullName=function(){
return surname+","+name;
}
this.getAge=function(){
return (new Date().getYear() - .dob.getYear()) ) ;
}
}
Person.prototype.getGender=function(){
var sex=this.sex,tolowerCase();
if( sex=='male' || sex=='m' )
return 'male';
else if( sex=='female' || sex=='f' )
rerturn 'female';
else
return 'god knows';
}
Person.prototype.getSpecies=function(){
return 'mammal';
}
In the above example, any instantiating code has only access to getFullName() , getAge() functions and ’sex’ variable of person object.
But we allow ’sex’ variable to be declared in two forms, long and short. And we return ’sex’ in long format with the help o getGender() helper function.
The above example can be broken down as following;
All variables except sex are private as they are constructor-scoped.
getFullName() and getAge() are privilaged function that have access to private variables name, surname and sex and thus are privileged/protected functions.
getGender() is a public function that has access to public variable sex.
the new getSpecies() is a public function that returns a value that’s entirely in its own scope.
So, there we have it, private, privileged and public access in javascript.
If we want to use module pattern the above can be modified to:
var Person= function(name ,surname, sex, dob){
this.sex=sex;
return{
getFullName:function(){
return surname+","+name;
},
getAge:function(){
return (new Date().getYear() - this.dob.getYear()) ) ;
},
getSpecies:function(){
return 'mammal';
}
}
}
An example of creating static object with private and public scope:
var Human = function() {
var species = "mammal";
return {
alert: function(){alert(species);}
};
}();
Human.alert();//displays 'mammal'
Here the variable species is private.
The function gets executed immediately due to () at the end of the function definition and will return a public static method alert()
That sums up variable scopes in javascript.
