JavaScript notes

Functionality, scoping and asynchronous executions are three interesting features of JavaScript. This blog notes down some points:

  • Functionality of JavaScript
  • Scoping, this, and bind()
  • The closure pattern
  • Asynchronousity and callback hells

    JavaScript the Function Programming Language

  • Everything is either a function (instantiated with function) or an object (instantiated with var).
  • Functions can be function parameters or return values.
1
2
3
4
5
6
7
8
9
10
function plot_graph(evt) {
// Code to plot graph
}

var btn = document.getElementById('plot');
btn.onclick = plot_graph;
btn.addListener('onclick', plot_graph);
btn.onclick = function() {
// Code to plot graph
}
  • Functions can be called upon definition.
    Think about this scenario where different canvas should be inflated with data.
1
2
3
4
5
6
7
8
9
function plot_graph(canvasid) {
// Code to plot data to canvas having id canvasid
}
var btn = document.getElementById('plot');
for (i = 0; i < N; i++) {
btn.onclick = function(x) {
plot_graph(x);
}(i);
}
  • Functions can be invoked with call() or apply()
    call() and apply() are two prefixed JavaScript function methods. Both methods take in an object as its first parameter.
    1
    2
    3
    4
    5
    function add(a, b) {
    return a*b;
    }
    object = add.call(object, 3, 4); // returns 12
    object = add.apply(object, [3, 4]); // returns 12 too
    Note that by invoking the functions in this way, their this value are explicitly set.

Ok so what is this?
Every piece of code has an owner. this refers to its owner object. If the code is global, then this refers to the browser window object.
bind(), call(), and apply() allows us to specify this explicitly and borrow functions. See this blog for more detailed explanations.

Scoping of JavaScript

A scope is a region in which the values of variables can be read valid. What are JavaScript’s scoping rules, then?

  • Global scope is global; functional scope resides within functions.
  • When a function or a variable is defined within a child scope, its parents cannot read it; the reverse goes the other way.
    Following is an example of two js files placed within the same directory.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // File1.js
    function outsideFunc() {
    var msg = "You can read me.";
    function innerfunc() {
    console.log('msg: ' + msg); // Can read
    var innerMsg = "You cannot read me from outside.";
    }
    console.log('innermsg: ' + innerMsg); // undefined
    }
    1
    2
    3
    4
    // File2.js
    function otherFileFunc() {
    outsideFunc(); // You can successfully call it
    }
  • When you declare a variable in a scope, it automatically gets shifted to the head of the scope; while the initialization is not shifted.

    1
    2
    3
    4
    5
    6
    7
    8
    function test() {
    var msg1 = "Declared and initialized at the head";

    console.log('msg1: ' + msg1); // prints the msg
    console.log('msg2: ' + msg2); // empty string
    var msg2 = "Declared and initialized at bottom";
    console.log('msg2 after: ' + msg2); // prints the msg
    }

And How About Closure?
Closure is similar to Java’s Singleton (protected constructor but does the instantiation job only when getInstance() method does not find the instance).
This example is taken from the W3S tutorial.

1
2
3
4
5
6
7
8
var add = (function() {
var counter = 0;
return function() {return counter += 1;}
})();
add();
add();
add();
// The counter is now 3

The wonderful thing about this counter is that nobody else have access to its counter, and that the funciton add() returns a function that adds its counter.

XMLHttpRequest and Asynchronous functions

AJAX brings in asynchronousity when it works with server which may take a long time to respond. Since JavaScript is single-threaded, asynchronousity is handled via callback functions, which comes from the line “call me back when you have time”.

Callback hells

  • Look at the following example:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    $.ajax({
    type: "POST",
    data: somedata,
    success: function(resposne) {
    $.ajax({
    type: "POST",
    data: somedata,
    success: function(response) {
    $.ajax({
    type: "POST",
    data: somedata,
    success: function(response) {
    console.log("Ahhh how many layers are you down here?");
    console.log("You are now trapped in the callback hell!");
    }
    error: function(response) {;}
    });
    }
    error: function(response) {;}
    });
    }
    error: function(response) {;}
    });

Resolving callback hells: error handling and waterfall

  • Two solutions: async.js and Promise.
  • They offer interfaces to handle the cases of success and error. In addition, they make the code structures linear (instead of the deep-down-the-hell in the example above).