Functionality, scoping and asynchronous executions are three interesting features of JavaScript. This blog notes down some points:
- Functionality of JavaScript
- Scoping,
this
, andbind()
- The closure pattern
- Asynchronousity and callback hells
JavaScript the Function Programming Language
- Everything is either a function (instantiated with
function
) or an object (instantiated withvar
). - Functions can be function parameters or return values.
1 | function plot_graph(evt) { |
- Functions can be called upon definition.
Think about this scenario where different canvas should be inflated with data.
1 | function plot_graph(canvasid) { |
- Functions can be invoked with
call()
orapply()
call()
andapply()
are two prefixed JavaScript function methods. Both methods take in an object as its first parameter.Note that by invoking the functions in this way, their1
2
3
4
5function add(a, b) {
return a*b;
}
object = add.call(object, 3, 4); // returns 12
object = add.apply(object, [3, 4]); // returns 12 toothis
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
8function 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
8var 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) {;}
});