Variable visibility in javascript

Every function has it’s own scope. A place where we can declare variables that are only available within the function it’s self. We’ve already seen how this can create private variables in a constructor. But there is much more to be said about variable visibility.

Understanding scope

Programmers familiar with any C-like language will be familiar with scope. In those languages any block in curly braces { and } will have it’s own scope. This is not true for javascript, which might be confusing to newcomers to the language. In javascript only functions have their own scope. This means that variables defined inside a function can not be accessed outside it.

foo = 1;
function bar() {
    // define a variable in a new scope
    var foo = 2;

    if (true) {
        // redefine foo in the function scope
        var foo = 3;
    }
    return foo;
}
baz = bar();
foo; // 1
baz; // 3

It is very important that we do not forget the var statement when creating variables inside a function. If we don’t use the var statement, the value will be assigned to the global variable, where it will at best cause bugs in our code, and at worst cause bugs in other code running on the page. It is also highly recommended that we only use one var statement per function, and that we put it at the top of the function. This has to do with the order in which functions are run. Something that goes beyond what I want to cover in this article.

Public, private and protected variables

In classical OOP languages, we can define the visibility of properties and methods on our classes. There are three levels of visibility:

Public
Visible to anyone
Private
Only visible to methods inside the class
Protected
Only visible to methods inside the class and any descendent of the class

If you’ve read my previous posts you might have noticed I’m already using public and private variables inside my constructors. Variables declared with var are private, and variables assigned as properties to ‘this’ are public.

function Foo() {
    var myPrivate = 1;
    this.myPublic = 2;
}

But we are missing protected variables here. And using prototype there is no way to get them. Now there are a few complicated constructions out there which can lock and unlock variables to ensure that only the right objects can access restricted variables on an object. If these were the only solution they might be worth considering. But when we use the caller extension pattern, there is a much simpler solution.

function Foo() {
    var myPrivate = 1,
        protect   = {
            myProtected : 3;
        };

    this.myPublic = 2;
    if (this instanceof Foo === false) {
        return protect;
    }
}

function Bar() {
    var protect = Foo.call(this);

    this.myPublic; // 2
    protect.myProtected; // 3
}

Storing our protected variables in an object, and returning that object at the end of the constructor, gives both Foo and Bar a second object they can share properties on (the first being ‘this’). By checking if ‘this’ isn’t an instance of Foo before returning we ensure that protect isn’t returned when Foo is constructed with new. Because objects are passed by reference in javascript, both Foo and Bar have the same object, so changes done in one of the constructor will effect the other. And because protect is kept private inside both Foo and Bar, it can not be accessed from outside the scope of either one of these constructors.

Another useful feature here is that if Foo is constructed with the new statement, protect is not return, and so doesn’t overrule the constructor. One thing to note is that we can’t use the variable name ‘protected’, as this is a restricted key word in javascript – even though it doesn’t have any purpose. So I’d recommend using ‘protect’ consistently across our applications.

Closing thoughts

A web page is a foreign environment. We don’t know for sure what is or will in the future be running on them. The fewer things in your application other scripts can mess with, the better. Keeping variables private should be the rule, not the exception, and function scope is the only way to do this. So every javascript programmer should have a firm understanding of it.

This entry was posted in Javascript and tagged , . Bookmark the permalink.

One Response to Variable visibility in javascript

  1. alexis says:

    necesito tener JavaScript para poder abrir mi facebook

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>