Javascript core concepts for backend developer

Javascript for backend developer

This post is a summary of what I’ve learned about “modern” Javascript core concepts including Scope, Closure, Function, Object Prototype, Module Export/Require.

Scope and Closure

In Javascript, every variable or function has a scope where it can be accessed or not. Let’s learn scope through examples:

Global scope

var myPoint1 = 1;

function showPoint1() {
	console.log(myPoint); // displays 1
}

showPoint1();

myPoint1 is declared as global scope so it can be accessed within any scope. In this example, it is called legally in the scope of showPoint1() function.

Local scope

function showPoint2() {
	var myPoint2 = 2;
}

console.log(myPoint2); // error

myPoint2 is declared within the scope of showPoint2() function. So, it cannot be accessed at global scope.

Closure

Official definition of closure:

Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.

And this is my understanding of closure: you can declare function in function - nested function (We will learn more about this at Function part). The inner function can access all the variables of the outer function. Let’s do an example:

function outerFunction1(myPoint3) {
	function innerFunction1() {
		console.log(6+myPoint3);
	}
	innerFunction1();
}

outerFunction1(3); // displays 9

In this example, outerFunction1 is instantiated with parameter 3. Then, the outerFunction1 is instantiated and it also ‘remembers/contains’ the myPoint3 parameter value of the outerFunction1 (closure mechanism); that’s why the innerFunction1 can access myPoint3 variable properly.

So, can an outer function access the variables within the scope of inner function? Let’s check:

function outerFunction2() {
	function innerFunction2() {
		var myPoint4 = 4;
	}
	console.log(myPoint4);
}

outerFunction2();

The answer is no. It will show error that myPoint4 is not defined.

=> The inner function can access variables of the outer function but not otherwise.

Anonymous, self-executing function

Thanks to the scope of Javascript, when you develop a script that you want to integrate to other existed web pages, then you should wrap your code in anonymous, self-executing function in order to not conflict with existed code:

(function(){
    // Your code
})();

Function

Offical definition:

In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object.

Define traditional function

Traditionally, you can define a function first and call it later.

function helloThere() {
	console.log('Hello');
}

helloThere(); // displays Hello

No problem, right?

Function can be defined and assigned to a variable

You can also define a function and assign it into a variable

var pet = function (type) {
	console.log('A '+type);
}

pet('dog'); // displays - A dog

Function can also be declared in an object

var boss = {
	name : 'Big Boss',
	pay : function () { console.log('$100'); },
};

boss.pay(); // displays - $100

Function returns Function

In function, you can return a function that you defined in the parent function scope. Let’s see an example from [7]:

function makeCounter() {
	var current = 0;
	var p = function process(x) {
		if (x >= 0) { current = x; }
        if (current < 0) { return 0; }
        console.log(current--);
	}
	return p;
}

var c = makeCounter();
c(42); // Displays - 42
c();   // Displays - 41
c();   // Displays - 40

In this case, the function makeCounter() returns p, which keeps the reference to the function process(). When we instantiate the variable c and set parameter value 42 for x, the variable p is then instantiated and it also remembers the current of parent function. As a result of that, whenever we call c() again, it calculates based on the variables that it ‘remembers’.

One more thing to pay attention here, what if we set return p() in the above code?

function makeCounter() {
	var current = 0;
	var p = function process(x) {
		if (x >= 0) { current = x; }
        if (current < 0) { return 0; }
        console.log(current--);
	}
	return p(); // The difference is here, we return p()
}

var c = makeCounter();
c(42); // Displays - 42
c();   // Displays - 41
c();   // Displays - 40

So, it will show error because variable c now is not a function. It’s true because when we call return p(), it means that we want to run and return the result of function process().

Function as a parameter of other function - Callback function

In Javascript, you can set a function as a parameter of another function.

function printMessage (message) {
	console.log(message)
}

function processResult (result, aCallbackFunction) {
	var message = '';
	if (result == 0) {
		message = 'Oh! It failed!';
	} else {
		message = 'You made it successful!';
	}
	aCallbackFunction(message);
}

processResult('done', printMessage); // Displays - You made it successful!

In this example, we declare 2 functions: printMessage and processReult(). The processResult has 2 parameters: result parameter and aCallbackFunction parameter - which is a function that we will call when we need to do something after processing in the processResult(). Later, we call processResult() and we supply 2 params values: ‘done’ for result param - printMessage() function for aCallBackFunction param.

Besides, we can declare an anonymous callback function as the parameter without defining it first:

function processResult (result, aCallbackFunction) {
	var message = '';
	if (result == 0) {
		message = 'Oh! It failed!';
	} else {
		message = 'You made it successful!';
	}
	aCallbackFunction(message);
}

processResult('done', function(message) {
	console.log(message);
});

This example produces exactly the same result like the above example.

The way that we declare callback function for one function is useful for special cases:

  1. Asynchronous programming: Sometimes, in a function, it takes time to finish a task like sending request to server and waiting for response. In that case, when that task is running, other tasks have to wait. Javascript enables async programming for us to deal with this situation: While a task is running and not finished yet, we call a callback function to do other task like showing the progress.

  2. Event Listeners/Handlers: When there is an event triggered, we use callback function to handle that event. You usually see this pattern in using Jquery for working with DOM elements or making AJAX requests, etc.

Object and Prototype

Offical definition:

All objects in JavaScript are descended from Object; all objects inherit methods and properties from Object.prototype.

So, what does it means?

  • Array in Javascript is an Object.
  • String in Javascript is an Object
  • Function in Javascript is an Object.
  • etc.

And as we knew that Function is a special kind of object, so it can have properties. It also inherits a special proerty called prototype (which is an empty object) from the Object. When an object is constructed, it inherits all of the properties of its constructor’s prototype. [5]

As a result of that, you can use Function to declare something like “Class” in OOP Programming.

‘Class’ definition

var Phone = function (number) {
  // Initialization
  this.number = number;
}

Add methods

You can add methods like this way

Phone.prototype.call = function () {
	console.log('Calling...!');
}

Phone.prototype.sms = function (message) {
	console.log('Sending sms: '+message);
}

or this way (because prototype property is also an object)

Phone.prototype = {
  call: function () {
    console.log('Calling...!');
  },
  sms: function (message) {
    console.log('Sending sms: '+message);
  }
}

Call and use

var p = new Phone('007');
p.call(); // Displays - Calling...!

Module Export and Require

In javascript, you can create a module in one file and require that file at other file to use that module.

For example, we will create 2 files:

pet.js

We define the Pet module

'use strict';

var Pet = function (petName) {
	this.myName = petName;
}

Pet.prototype.say = function(message) {
	console.log(this.myName +' says '+ message);
}

module.exports.Pet = Pet;

index.js

We require that Pet module and use it

'use strict';

var pet = require('./pet');

var p = new pet.Pet('Husky');

p.say('blah blah'); // displays - Husky says blah blah

Hope this helps!

References

1/ Javascript MDN

2/ Closure và scope trong javascript

3/ Explaining JavaScript Scope And Closures

4/ Node.js, Require and Exports

5/ JavaScript constructors, prototypes, and the new keyword

6/ Stop Nesting Functions! (But Not All of Them)

7/ What are the reasons to use ‘return function’ in JavaScript?

8/ What are the reasons to use ‘return function’ in JavaScript?

Written on March 18, 2016