Javascript variable scope, private protected and public

May 27th, 2009 | Posted by admin in front end | Javascript

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.

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

2 Responses

  • Nice post!
    But whenever I have to create class in JS I use Prototype API http://www.prototypejs.org/api/class/create (I am a bit lazy ;) )

  • admin says:

    Its good to have a library handy to take care of simple things like creating classes.
    It sure makes life little easier.
    But I think its better to do simple things on your own for the sole reason of making one’s code less dependent on third party libraries.
    And also to ensure another person looking at or working with the code won’t require to learn a framework to be able to understand, modify, extend your code in future.

    I use YUI library pretty heavily these days. I’m stuck with YUI because I’m a big sucker for their dataTable widget and I build a CRUD framework around it 1-2 years back. I’m stuck with YUI on that but I’m quite happy because their libraries are very modular and well-tested and well documented.

    But at the moment, I’m trying to rewrite all javascript libraries I developed at home and at work so that I can be less dependent on third party libraries.
    At least to an extend where library code and function calls don’t creep into the business logic parts of the code. and I can abstract them away into my own objects so that calls to those library functions are indirect which will allow me to switch third-party libraries in future without having to rewrite everything.

    I did use prototype initially when I was learning javascript and at that time I thought it was the coolest thing to ever happen to javascript, I still believe it is, but I happen to move to YUI for other reasons.



Leave a Reply

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>