Blog

JavaScript: Exception Handling

Exception handling in JavaScript is extremely similar to that in C# or Java. Js utilizes the familiar try-catch blocks to capture exceptions and handle them. You simply wrap code that might throw an exception in the try and then provide a catch to handle the captured exceptions.

Unlike C# and Java, JavaScript does not allow multiple catch blocks nor does it handle capturing exceptions based on specificity. For this you must implement your own code by checking the exception name or using reflection methods to identify the exception types you are after. This is a little cumbersome but doable.

'use strict';

// Exception Handling
//  1. Use 'throw' to create and throw an Exception
//  2. Use the 'name' property to give the Exception an identifiable name
//  3. Use the 'message' property to give the Exception a meaningful message for the user
//  4. Standard Try-Catch as we are used to in Java and C#
//  5. Place code which might create an error in the 'try' block
//  6. Place rescue code in the 'catch' block
//  7. 'try' blocks can only have one 'catch' and one only
//  8. Must check Exception name in order to handle more than one type of Exception at a time

try{
    // Code that can cause an error during execution

    // Code actually throwing an Exception
    throw {
        name: "CustomErrorType",
        message: "I just threw an error at you."
    }
}catch(error){
    if(error.name === "SomeOtherError"){
        // Do something here
    }

    if(error.name === "CustomErrorType"){
        // Code to rescue processing from the error
        console.log("Captured and error: " + error.name);
        console.log("Its message is: " + error.message);
    }
}

JavaScript: Cascading Methods (Method Chaining)

One extremely useful programming pattern that can be implemented in JavaScript is that of ‘cascading methods’ also known as ‘method chaining’. Method chaining is accomplished in JS by simply returning the object that was just operated on as the result of the method call. By doing this, a developer can call a method and then instantly call another method on the same object without referencing the object or capturing the result of the previous method call.

This is possible due to the fact that the result of a method is returned directly after the method call itself and is therefore used as the object of interest for the following (chained) method call (see example code below).

'use strict';

// Cascading/Chaining Methods
//  1. Return 'this' instead of 'undefined' at the end of your Methods
//  2. This allows the focused Object to be returned and additional Methods to be called on it

var person = {
    first_name: 'First name not provided',
    middle_initial: 'initial not provided',
    last_name: 'Last name not provided',
    age: 'Age not provided',

    change_first_name: function(new_name){
        this.first_name = new_name;
        return this; // Return the current object
    },

    change_last_name: function(new_name){
        this.last_name = new_name;
        return this; // Return the current object
    },

    change_middle_initial: function(new_initial){
        this.middle_initial = new_initial;
        return this; // Return the current object
    }
};

// Call each of the Object's methods one right after the other
person.change_first_name('Tim').change_middle_initial('').change_last_name('Clark');

console.log('First Name: ' + person.first_name);
console.log('Middle Initial: ' + person.middle_initial);
console.log('Last Name: ' + person.last_name);

JavaScript: Reflection

JavaScript provides some rudimentary reflective abilities, or the ability for a computer to examine, identify, interpret, and potentially alter the structure of its code, state, and behavior at runtime. The heavy hitters in this arena are ‘typeof’ and ‘hasOwnProperty’.

Typeof allows a JS script to ask an object what its type is before it is acted upon. Due to JavaScript’s loosely typed structure, this ability can come in handy when it is possible that a function might receive a parameter that may be of the wrong type or of differing types and the cases need to be handled separately.

HasOwnProperty allows a JS script to ask an object if its supports a particular property. Properties can be both state properties as well as function properties.

'use strict';

// JavaScript Reflection
// Identifying the types of objects as well as whether or not objects have specific variables or functions
var person = {
    firstName: 'First name not provided',
    middleInitial: 'initial not provided',
    lastName: 'Last name not provided',
    age: 'Age not provided',
    sayYourName: function(){
        return "Hello, I am " + this.firstName + " " + this.lastName;
    }
};

//  1. Discovering the type of an Object using 'typeof'
console.log(typeof person.firstName); // String
console.log(typeof person.sayYourName()); // String: based on return type of the function
console.log(typeof person.blah); // Undefined

//  2. Discovering if an Object has a particular property using 'hasOwnProperty'
console.log(person.hasOwnProperty('lastName')); // True
console.log(person.hasOwnProperty('sayYourName')); // True
console.log(person.hasOwnProperty('blah')); // False

JavaScript: Prototype Inheritance System

Unlike C# and Java, JavaScript uses a preexisting “prototype” object to create all new objects. This means that instead of using static templates to create objects (classes), JavaScript takes either the default prototype object or one of your choosing and duplicates for use as a new object. This duplicate is then modified on-the-fly by the script you write to convert that new object into the object you desire, this can be done by adding variables and functions to the object providing it with its own state and behavior.

'use strict';

// Prototype Object Builder
//  1. Utility Function used to make Prototypal Inheritance easier to accomplish in one action
//  2. Use by passing in a useful base Object which you want to use as the prototype for the new Object
function objectBuilder (protoObject){
    var F = function(){};
    F.prototype = protoObject;
    return new F();
}

// All Objects are linked to a Prototype Object
// 1. All objects created via Literals are linked to Object.prototype by default
// 2. The prototype link is unidirectional, properties of the prototype object are pulled down by the inheriting object
// 3. Updating does not affect the Prototype object since the link is unidirectional
// 4. Augmentation of the Prototype object (adding properties/methods) is instantly available to all inheriting objects

//---------------------------------------------//

// Useful Object for Prototyping purposes
var personPrototype = {
    firstName: 'First name not provided',
    middleInitial: 'initial not provided',
    lastName: 'Last name not provided',
    age: 'Age not provided',
    sayYourName: function(){
        return "Hello, I am " + this.firstName + " " + this.lastName;
    }
};

// Creating custom Person Object from Person Prototype
var tim = objectBuilder(personPrototype);

//---------------------------------------------//

// Displaying that the new Tim Person Object has inherited
// the variables of the Prototype Object
console.log(tim.firstName);
tim.firstName = 'Timothy';
console.log(tim.firstName);

console.log(tim.middleInitial);
tim.middleInitial = 'L';
console.log(tim.middleInitial);

console.log(tim.lastName);
tim.lastName = 'Clark';
console.log(tim.lastName);

//---------------------------------------------//

// Displaying that the new Tim Person Object has inherited
// the functions of the Prototype Object
console.log(tim.sayYourName());

// Adding variables or functions to the Prototype are
// instantly available to inheriting Objects
personPrototype.walk = function(){
    return "Walk, walk, walk...";
};
// Prototype Object now has method
console.log(personPrototype.walk());
// Inherited Object now has method
console.log(tim.walk());

//---------------------------------------------//

// Displaying that augmenting the inherited Object
// does not affect the linked Prototype object
tim.run = function(){
    return "I'm running around like a chicken with its head cut off.";
};
tim.hairColor = "brown";
// Inherited Object now has the new Function
console.log(tim.run());
console.log(tim.hairColor);
// Prototype Object is NOT affected
try{
    console.log(personPrototype.run()); // Returns an error, function does not exist
}catch(error){
    console.log("personPrototype: " + error.message);
}
console.log(personPrototype.hairColor); // Returns undefined, value does not exist

//---------------------------------------------//

// Displaying that changing the values of the Prototype Object's variables does not affect the inheriting Objects
personPrototype.firstName = 'WOOO HOOO';
console.log(personPrototype.firstName);
console.log(tim.firstName);

JavaScript: Objects

Class-Free

Objects in JavaScript are class-free, meaning that they are not created via a static class (template) as they are in object-oriented programming languages such as C# or Java. Instead, JS objects are created through a prototypal system (a topic for another post). There is a base prototype object in JavaScript from which all other objects are created.

Literal Notation

Because of this prototypal system, all custom objects are created inline in a given script. Custom JS objects are primarily created through what is called a literal notation, they are ‘literally’ written out line-by-line in the script and are ‘literally’ built in memory as the script executes line-by-line.

Mutable Key/Value Collections

Objects in JavaScript are mutable, meaning they can be altered over time as a script executes and it is used, passed around, and manipulated by the script. They are also keyed collections, meaning JS objects are pretty much dictionaries with keys indicating named properties and their associated values. Due to this, JS object properties can be accessed in two ways, the traditional ‘Dot’ notation as seen in object-oriented programming languages such as C# and Java or through array like notation utilizing index operators (square brackets).

Pass-By-Reference

JS Objects are always passed by reference, meaning as an object is passed from function to function or throughout a script it is only its reference in memory that is being passed around not the actual object. This also means that the object is also not being copied or duplicated in any way as it is being passed around.

'use strict';

// JavaScript Objects
//  1. Mutable: they can be altered at will
//  2. Keyed Collections: keys point to values, other objects, or functions
//  3. Class-free: they are never predefined, no template
//  4. Keys are strings
//  5. Quotes around key strings are optional if the string is not a JS key word and is a proper JS identifier
//  6. Objects can be embedded
//  7. Objects are always passed by reference (never copied)

var emptyObject = {};

var person = {
    first_name: "Tim",       // Quotes optional since the property name string is a valid JS Identifier
    "last-name": "Clark",    // Quotes required since property name string is invalid
    address: {
        street: "143 South Main",
        city: "Salt Lake City",
        state: "Utah",
        zip: "84111"
    }
};

// Retrieval of Object Properties
var firstName = person.first_name;  // . notation can be used due to valid JS Identifier
var lastName = person["last-name"]; // [] bracket notation required due to invalid JS Identifier

// Undefined: retrieving non-existent properties results in the Undefined value
var middleName = person.middle_name; // middleName === undefined [property does not exist]

// TypeError Exception: when retrieving a non-existent property from a non-existent property
var account = person.account;        // Undefined
var balance = person.account.balance; // TypeError
// Avoid error and get back just undefined
var account = person.account && person.account.balance; // Undefined

// Property Updates by assignment
person.first_name = "Freddy";

// Augmentation based on Non-existent Property Assignment
var middle_initial = person.middle_initial; // Undefined
person.middle_initial = "Argyle";
middle_initial = person.middle_initial; // "Argyle"

JavaScript: Closures

Simply put, a closure is a function in which another function, the inner function, is defined. The important part, when it comes to closures, is that the inner function remembers the environment in which it was created. What this really means is that when the inner function references the variables of the outer function, the inner function retains references to these variables even after the outer function terminates its execution and is no longer needed.

So why is this a useful feature of JavaScript, probably the most common use is as a ‘hack’ to create private state (variables) specific to a function and which can only be altered by the function that maintains a reference to that state. If you are familiar with C# or Java this can be compared to what is called encapsulation, where an object has state (variables) within it which only it can modify.

'use strict';

// Closures
//  9. Closures: Functions can be declared inside of other Functions
//     the Function has access to its own Parameters and Scope
//     but it also has access to the Parameters and Scope of the
//     Functions it is nested within
function encapsulator (param){
    var variable_in_scope = "I am in the Encapsulator.";

    function inner_function(inner_param){
        console.log("Inner Function param: " + inner_param);
        console.log("Outer Function param: " + param)
        console.log("Outer Function scope Variable: " + variable_in_scope);
    }

    try{
        console.log("Attempting to access Inner Function param from Outer Function: " + inner_param);
    }catch(error){
        console.log("ERROR: You cannot access the scope of an Inner Function: " + error.message);
    }

    inner_function("You are entering the Inner Function");
}

encapsulator("You are calling the Outer Function");