Offline
Online
Viewers

Understanding JavaScript Execution Scope

By utilizing the var keyword as a literal, pseudo structures or pseudo namespaces can be created.

Pseudo Structures:

All members and methods within a pseudo structure are public. The psuedo structures are non-instantiable. To access a member of a pseudo structure, use the structureName.member or structureName.functionName() syntax.

[codesyntax lang=”javascript”]

var structureName = {
    member1: "value",
    member2: "value",
    member3: "value",

    functionName: function(){
        this.member1 = "new value";
        this.member2 = "new value";
        this.member3 = "new value";
    },

    functionName2: function(){
        this.member1 = "new value";
        this.member2 = "new value";
        this.member3 = "new value";
    }
}

[/codesyntax]

As you can see from the above example, a psuedo structure was created by assigning the structureName variable a literal set of statements. The structureName variable can now be accessed the same way a structure would be.

One of the more complex ideas to get a grasp of is execution scope within object classes. Object class are nothing more than functions that utilize JavaScript’s execution scope to their advantage.

Object classes:

Javascript object classes support public, private, protected and static members and methods.

[codesyntax lang=”javascript”]

function className(){

    this.publicMember = "public";
    var privateMember = "private";
    protectedMember = "protected";

    function privateFunction(){
        this.publicMember = "new value";
        privateMember = "new value";
        protectedMember = "new value";
    }

    var privateFunction2 = function(){
        this.publicMember = "new value";
        privateMember = "new value";
        protectedMember = "new value";
    }

    this.publicFunction = function(){
        this.publicMember = "new value";
        privateMember = "new value";
        protectedMember = "new value";
    }

    protectedFunction = function(){
        this.publicMember = "new value";
        privateMember = "new value";
        protectedMember = "new value";
    }

}

className.staticMember = "static";

className.staticFunction = function(){
    //static function body
}

[/codesyntax]

As the above example demonstrates, public, private, protected and even static members and methods can be created by understanding the execution scope of the object. In this case a private variable can be create by assigning the var keyword. This makes the variable only accessible from within the object or from one of its member functions. Protected members and variables can be declared by omitting the var keyword. These variables are then accessible in the same context as private variables, but can also be accessed from inheriting objects or classes. The “this” keyword specifies public accessibility to the members and methods. Static members and methods can be declared by specifying the objectName.memberName = function(). These members and methods can be accessed in the exact same way that standard static members and methods can be accessed.

Class Inheritance:

JavaScript classes can be a powerful asset if you know how to use them. For most, inheritance and base class handling are too complex to be used in JavaScript, I’m hoping to shed some light on this mystery. Consider the base class below.

[codesyntax lang=”javascript”]

function BaseClass(){

    var privateVariable = 0;
    protectedVariable = 0;
    this.publicVariable = 0;

    function privateMethod(){
        alert("private");
    }

    this.publicMethod = function(){
        alert("public");
    }

    protectedMethod = function(){
        alert("protected");
    }

}

[/codesyntax]

This simple BaseClass has 3 member variables and 3 member functions with each a private, protected and public scope respectively. Notice the subtle differences which allow for different access levels. The “this” prefix binds the method or variable to the instance of the class. The “var” prefix makes the method or variable private to the instance of the class. The lack of any prefix or keyword makes the method or variable a protected member of the class instance. All of this was covered in the first part of “Understanding JavaScript Execution Scope”, now we introduce complexity by adding an inheriting class.

[codesyntax lang=”javascript”]

function SubClass(){

}
SubClass.prototype = new BaseClass();

[/codesyntax]

The SubClass inherits from BaseClass by use of the prototype member. Now for the interesting part, once you instanciate the SubClass you will have access to the members of the BaseClass as you would expect to. Private functions will not be accessible, but protected and public methods will be. Consider the following:

[codesyntax lang=”javascript”]

function SubClass(newValue){

    protectedVariable = newValue;

    this.display(){
        alert(protectedVariable);
    }

}
SubClass.prototype = new BaseClass();

[/codesyntax]

The modification to the SubClass sets the “protectedVariable” member of BaseClass to the “newValue” passed into the constructor of the class. Pretty straight forward right? But now watch, add this to the script to test it:

[codesyntax lang=”javascript”]

var sc1 = new SubClass(2);
sc1.display(); //alerts 2 - correct

var sc2 = new SubClass(4);
sc2.display(); //alerts 4 - correct

sc1.display(); //alerts 4 - WTF?

[/codesyntax]

At this point you’re probably wondering what’s going on? Most of the JavaScript books will tell you this is how you do inheritance, but there’s a problem isn’t there. That last display was from our first instance, it should have displayed “2” but instead it displayed “4”, why? Here’s why, because only one instance of the “protectedVariable” is shared shared between the two seperate instances of the SubClass, this is something to keep in mind when building your JavaScript classes. To keep instance members safe, create public (“this” bound) members or private (“var” bound) members. Now consider the following
modification:

[codesyntax lang=”javascript”]

function BaseClass(){

    var _n = 0;

    this.setN = function(n){
        _n = n;
    }

    this.getN = function(){
        return _n;
    }

}

function SubClass(newValue){

    this.setN(newValue);

    this.display = function(){
        alert(this.getN());
    }

}
SubClass.prototype = new BaseClass();

var sc1 = new SubClass(2);
sc1.display(); //alerts 2 - correct

var sc2 = new SubClass(4);
sc2.display(); //alerts 4 - correct

sc1.display(); //alerts 4 - WTF? Again?

[/codesyntax]

What happened? I thought you said private and public members would be safe, but it acted the same as a protected member. Yes, and here’s why:

[codesyntax lang=”javascript”]

SubClass.prototype = new BaseClass();

[/codesyntax]

Most of the JavaScript books and tutorials will tell you that this is how you do inheritance in JavaScript, and they’re halfway right, but there’s an obvious problem with this approach. There will only be one instance created of the BaseClass for each and every subsequent instance of the SubClass, in otherwords, they’re sharing state. Kind of cool, but it’s not what we wanted, so here’s the fix:

[codesyntax lang=”javascript”]

function SubClass(newValue){
    SubClass.prototype = new BaseClass();

    this.setN(newValue);

    this.display = function(){
        alert(this.getN());
    }

}
SubClass.prototype = new BaseClass();

[/codesyntax]

Notice that the first line inside the SubClass is also the same as the line immediately after the class definition. This may seem a little redundant, but it ensures that a new instances of the BaseClass is created for every instance of the SubClass. Now try the test again:

[codesyntax lang=”javascript”]

var sc1 = new SubClass(2);
sc1.display(); //alerts 2 - correct

var sc2 = new SubClass(4);
sc2.display(); //alerts 4 - correct

sc1.display(); //alerts 2 - correct

[/codesyntax]

Everything is now good in the world of prototypical inheritance, but now comes another problem. When you start designing robust JavaScript classes that use heavy inheritance you are going to inevitably want to call base classes up the inheritance chain. Consider the following:

[codesyntax lang=”javascript”]

function BaseClass(){

    var _n = 0;

    this.display = function(){
        alert("BaseClass: " + _n);
    }

}

function SubClass(){
    SubClass.prototype = new BaseClass();

    this.display = function(){
        alert("SubClass: " + this.getN());
    }

}

var bc = new BaseClass();
bc.display();

var sc = new SubClass();
sc.display();

[/codesyntax]

Well, everything works as expected, but what about calling the BaseClass.display() function. There will definately come a time when we will need to call up the parent object chain. To do this, we make use of the prototype member:

[codesyntax lang=”javascript”]

SubClass.prototype.display();

//This will call the immediate parent object of SubClass, which of course is BaseClass. Try the following:

function BaseClass(){

    var _n = 0;

    this.display = function(){
        alert("BaseClass: " + _n);
    }

}

function SubClass(){
    SubClass.prototype = new BaseClass();

    this.display = function(){
        SubClass.prototype.display();
        alert("SubClass: " + this.getN());
    }

}

var bc = new BaseClass();
bc.display();

var sc = new SubClass();
sc.display();

[/codesyntax]

Notice, the BaseClass alert is displayed, then the BaseClass and the SubClass alert is displayed. Success, we now have a way to call parent methods in JavaScript. Simple right? That’s it for now and thanks for reading.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Affiliates