Hiding Scope in Javascript

Published On:
Amer Agovic Programming Language, Javascript
...
drawing

Hiding Scope in Javascript

Amer Agovic No Comments Programming, JavaScript

This is my first entry on Javascript. Over the years I used Basic, Turbo Pascal, Assembly, Perl, Python, C and C++, Java and C#. For most of that time I considered Javascript not really worthy my time. Somehow too loose for my taste.

It all changed once I embraced AJAX as integral part of the web application experience. Suddenly I realized that Javascript is actually quite useful, simple and powerful. In fact, now that I think of it, with a few concepts borrowed from Python or Matlab it could be the language for Machine Learning.

Anyways if you start learning Javascript they show you how to declare a variable and a function. From there you can slowly go deeper.

Variables and Functions

var primVar="Hello World";          // primitive type
var objVar={prop1:'Age',prop2:3};   // javascript object   
var arrVar=['Uno','Due','Tres'];    // javascript array
// this is a function, no input parameters and no return value
function doSomething(){
    console.log(primVar);
}

Variables in Javascript are similar to scalars in Perl or variants in Visual Basic. They can hold primitive data such as numbers, booleans or strings. Beyond primitive types a variable can represent an object or an array. If the properties of the variable are indexed by text it is an object if they are indexed by non-negative integers it is considered an array.

You realize that objects and arrays are kind of related when you try to enumerate the properties.

Iterating over Objects

for (var key in yourobject) {
    console.log(key, yourobject[key]);
}

This foreach loop will enumerate both objects. For arrays key will be an index while for regular objects it will be property name.
So far so good. Javascript is simple. In its basic form Javascript does not have many of the advanced keywords that Java or C# have. For example there is no class keyword.
Instead you define a function that acts as a constructor and if you use the “new” operator. It effectively instantiates an object of that type.

Defining Classes and Instantiating New Object

function OrRegExp(patterns,prefix) {
this.patterns = [];
for (var key in patterns) {
    var p=patterns[key];
    this.patterns.push(p);
}
};
OrRegExp.prototype.test = function (str) {
for (var key in this.patterns) {
    var p=this.patterns[key];
    if(p.test(str)) return true;
}
return false;
};
var myRegEx=new OrRegExp(".*","");
myRegEx.test('Hi There');

Observe the special property “prototype”. If you assign functions to that property it adds them as class methods.

Observe something else. Something very interesting and important. Something that made me go AHA!.

FUNCTIONS IN JAVASCRIPT ARE OBJECTS.

And since functions are objects you can assign them as values to other object properties. Properties that hold functions as value can be invoked of course. That is why you can call method “test” at the bottom of the last example.

But that is not the end of the story. It is the beginning that made me realize how powerful Javascript can be.

You see functions are objects and any variables and functions that you define inside a function live inside the scope of that object.

What it means is easiest explained with an example. Let us use a skeleton of a jQuery plugin as that example.

Anonymity and Scope of Functions

(function ($) {
var methods = {
    destroy : function(opts) {
    },
    init : function(opts) {
    }
}
$.fn.validator = function (methodOrOptions) {
    return function(methodOrOptions){
        return false;
    };
}
})(jQuery);

In the above code we first define a no-name function or anonymous function and call it immediately providing jQuery variable as parameter.

(function ($) {})(jQuery);

Inside this anonymous function an object is created that holds various helper methods such as “destroy” and “init”. Also inside the method we assign a function to a new property of variable “$.fn” and name it “validator”.

As you can see we are registering a jQuery validation plugin.

Functions that are created inside other functions remember their parent function. This is unlike old fashioned languages like C++ where scope of a function or frame is pushed on the stack and removed as soon as the function returns.

In Javascript, as shown here, when we invoke the jQuery plugin some time later using “$(‘#elmentId’).validator(‘blabla’)” it will return a trivial function that returns false. But most importantly the returned function sees the variable “methods” and can access it.

Any other inner function also sees the variable. But to the outside world the variable is inaccessible. We have managed to hide internal state of a plugin from the outside world.

To put everything together here is a skeleton of a jQuery plugin that allows us to call internal method via parameter as is recommended.

jQuery Plugin Template

(function ($) {
var methods = {
    destroy : function(opts) {
    },
    init : function(opts) {
    },
    verify : function(opts) {
    }
};
$.fn.validator = function (methodOrOptions) {
    var arg=arguments;
    var func=methods.init;
    if (methods[methodOrOptions] ) {
        func=methods[methodOrOptions];
        arg=Array.prototype.slice.call( arg, 1 );
    } else if ( methodOrOptions && typeof methodOrOptions !== 'object') {
        $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.popup' );
    }
    var verifyFunc=func===methods.verify;
    var verified=true;
    var ret=this.each(function () {
        if(!verifyFunc){
            return func.apply(this,arg);
        }else{
            // for verify we return first false
            verified=verified && func.apply(this,arg);
            return true;
        }
    });
    return verifyFunc?verified:ret;
};
}(jQuery));

In the method “$.fn.validator” we check if “methodOrOptions” is a property of “methods” variable. If it is we call the appropriate method and hand it all remaining arguments as there could be more than one.

The call to the selected method uses .each() iterator of jQuery except when method ‘verify’ is selected. Then it processes return values differently. For a validator this is useful because “verify” needs to return first false value after checking several elements. While all other methods are applied equaly to all elements selected by the jQuery selection using method call ” $(‘….’)”

The usage of a validation plugin built this way would then look like this:

Calling jQuery

var input_fields=$('#FirstName,#LastName');   // select input fields to validate
input_fields.validator('init');               // install validator state on each input field
if(input_fields.validator('verify')==true){   // if all fields validate submit form
form.submit();
}

Hopefully this tutorial helps you understand Javascript better. In the process we also mentioned jQuery and showed how jQuery plugins are structured.

...
Amer Agovic
Amer Agovic, PhD is the President and Founder at Reliancy. He has been the Chief Architect of the Reliancy's own software platform and has considerable experience in structuring and leading Software Development projects. His fields of expertise include Software Architecture, Robotics, Computer Vision and Natural Language Processing.