Advanced Javascript Concepts

This article explains how to use most advanced, but must learn Javascript concepts including Prototypes, Proxies and Callbacks.

Prototypes

Objects and arrays in Javascript, inherits properties and methods from prototype object.

let numbers = {1, 2, 3}
console.log(numbers);
js prototype in array

When you check console.log() of an Array or Object, You’ll see an internal property named __proto__ which points to the prototype object of the parent function. For example, an array inherits set of prototype methods from it’s parent Array function.

javascript prototype object
__proto__ property of an Array
check instance of Array
var numbers is an instance of Array function
Array is a function

If we look at Array.prototype, we will see same set of methods and properties exposed through property __proto__.

Comparison of __proto__ and Array.prototype confirm both points to same object

Now if we add a new method to the Array function, it will be inherited in any array you create.

Similarly, you can access or modify prototype object of custom functions you create, and it will be inherited by the instances.

Promises

Promise is an object in Javascript used to represent completion or failure of an asynchronous operation, and it’s resulting value.

A promise can be defined as below;

let promise = new Promise(function(resolve, reject) {
  // executor
});

Promise accepts a function (executor) as argument and it accepts two functions named resolve and reject as given in above example.

Executor can be a long running operation like database execution or web service call out. If operation is successful, resolve(value) can be called, else reject(error).

A promise can be in one of three states. Initially it will be in “pending” state, then it will be changed to “fulfilled” when resolve() or “rejected” when reject() is called.

Source: Mozilla.org

Here is a sample function returning a promise.

function promiseMe() {
    return new Promise(function (resolve, reject) {
        setTimeout(() => resolve("completed"), 10000);
    });
}

Syntax for consuming a promise.

.then(function(success){
        //handle success
    }, function(error){
        //handle error
    })

This is a sample code for consuming promiseMe() function created above. If resolve() is called it will execute console.log(success) and if reject(), then it will run console.log(error).

let trust = promiseMe();

trust.then(
    success => console.log(success),
    error => console.log(error)
);

Alternatively, reject can be handled with catch() and it will be invoked when a promise is either rejected or some error has occurred in execution.

let trust = promiseMe();

trust.then(
    success => console.log(success)
).catch(error => {
    console.error(error)
})

If you need some code to be executed when either success or rejected, you can use finally() as below.

let trust = promiseMe();

trust.then(
    success => console.log(success)
).catch(error => {
    console.error(error)
}).finally(() => console.log("final promise"))

Async/await

Async and await functions were introduced in ES8 which make asynchronous code easier to write and to read afterwards.

Basic async function can be defined as below.

async function hello() { return "Hello" };

hello();

It can be further simplified with an arrow function.

let hello = async () => { return "Hello" };
hello();

When executed, above function returns a promise. To consume async function, .then() can be used.

hello().then((value) => console.log(value))

or

hello().then(console.log)

await keyword can be used inside async function to pause execution of code until promise has fulfilled.

function promiseMe() {
    return new Promise(function (resolve, reject) {
        setTimeout(() => resolve("completed"), 10000);
    });
}

async function myPromise() {
  const msg = await promiseMe();
  console.log('Message:', msg);
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.