Featured post

Closures, Lexical Scoping And Scope chain In JavaScript

Closures...You have heard a lot, or might have tried to study from different sources, but failed to get the point. Well to under...

Monday 7 March 2016

Understanding ECMAScript 6


If you are a web developer than you already know what ECMAScript is. For rest of the readers, let me introduce you with it. ECMAScript is trademark scripting language specification which is standardized by Ecma International. Languages like JavaScript, JScript, ActionScript follows ECMAScript specifications. Also, these languages provide some additional features not included in specifications yet. Till date, 6 versions of ECMAScript standards has been released and 7th's work is in progress.



Earlier posts from this blog were completely based on ES5 and now I am introducing you with some new, cool features of ES6.

Constants


We have seen in this post how we can create properties of an object according to ES5:

var obj = {};
obj.createProperty({
      writable: false,
      configurable: false,
      enumerable: false,
      value: "Why everything is False :| "
});

Using above method, we can define property which can not be altered (because writable is false), not enumerable (child object will not iterate in for..in loop) and neither configurable (property can not be deleted with delete operator). This way is only and hell complicated to define attributes of a property.
Luckily, ES6 has introduced concept of constants. Constants are basically variables which can not be reassigned new content or can not be re-declared. Variable itself is immutable BUT if variable is assigned an object than that object can be altered later.

const PI = 3.141593;      // Assigns some value to PI variable.
PI = 5;      // Will not assign. Error: Re-assigning
console.log(PI);      // Still print 3.141593

Note


const obiWan = {
      side: "Light",
      padawan: "Anakin"
}
const obiWan = "What is wrong with this line";      // Error: Re-declaring
obiWan = {                        // Error: Re-assigning
      side: "Still Light.",
      padawan: "Darth Vader"
}
console.log(obiWan);      // It will still print old object because we are re-assigning object which won't work
obiWan.side = "Still Light.";      // This will work
obiWan.padawan = "Darth Vader"      // This will work too
obiWan.endResult = "Merges with force!!"      // Yup. This will also work.
console.log(obiWan);      // This will print altered object


Variable Block Scoping

JavaScript variables defined using var keyword only supports function level scoping. That is, variable will be accessible throughout the function no matter where it has been declared or defined within function. This is possible because JavaScript supports Hoisting. Hoisting means all the variable declaration will come up on the first line of function body no matter where in the body they are declared. But the definition will remain on the same line where it is.

var f = function() {
      function p() {
             // some code in p function
      }
      function q() {
             // some code in q function
      }
      var i = 10;
      var j = {}
}

Above code will be interpreted as

var f = function() {
      var i, j;                       // Hoisting: variable declaration will come up
      function p() {
             // some code in p function
      }
      function q() {
             // some code in q function
      }
      i = 10;
      j = {};
}

Hoisting helps in many situations but that does not suppress the need of block level scoping. ES6 has introduced a way to declare variable with block level scope using keyword let. When a variable is defined using keyword let instead of var then scope of that variable is within the block only. Block can be for loop, do..while, etc.

Lets take a scenario based on ES5

var separateI = [];
for (var i = 0; i <= 2; i++) {
      separateI[i] = function() { return i * 2 }
}
separateI[0]() === 0;      // False....Result: 6
separateI[1]() === 2;      // False....Result: 6
separateI[2]() === 4;      // False....Result: 6

Why??? Because value of i at the end will be 3 (in the last iteration of for loop. Refer Lexical Scoping for more information). How can we solve this problem? Using block level scoping.

let separateI = [];
for (let i = 0; i <= 2; i++) {
      separateI[i] = function() { return i * 2 }
}
separateI[0] === 0;      // True
separateI[1] === 2;      // True
separateI[2] === 4;      // True

This approach kind of replaces the need of closures here.

Function Block Scoping

Functions in ES5 only have function scoping, i.e., inner function will be visible in all over the scope of outer function. But ES6 has introduced a way where function's scope can also be set to the block only and not to whole outer function.

{
      function foo () { return 1 }
      foo() === 1      // True
      {
            function foo () { return 2 }
            foo() === 2      // True
      }
      foo() === 1      // True
}

This can be achieved in ES5 also, but with lot of functions.

(function() {
      var foo = function() { return 1 }
      foo() === 1      // True
      (function() {
            var foo = function() { return 2 }
            foo() === 2;      // True
      })();
      foo() ===1;       // True
})();

Classes

Ladies and gentlemen.. prepare yourself for the epic moment in history of web development..(Crowd cheering..fireworks explode...) Finally Classes are introduced in JavaScript.. We always used to implement classes by putting lots of efforts. We were never be able to use class as variable since it was a "reserved keyword" for "future use". Well, now we are living in future..future begins from  here..:D

Most typical way to define a class in JavaScript (before ES6):

var myClass = function(x, y) {
      this.x = x;
      this.y = y;
}
myClass.prototype = {
      toString: function() {
            return this.x + " " + this.y;
      }
}
myClass.prototype.constructor = myClass;

Class definition in ES6:

class myClass {
      constructor (x, y) {
            this.x = x;
            this.y = y;
      }
      toString() {
            return this.x + " " + this.y;
      }
}

I know..this one is hell easy..JavaScript has always been awesome but now it feels complete..
If we have classes then surely we will be having easier way of inheriting classes. Lets explore that too.

class anotherClass extends myClass {
      constructor (x, y, width, height) {
            super(x, y);            // Calls the constructor of super class
            this.width = width;
            this.height = height;
      }
}

Inheritance in earlier version:

var myClass = function(x, y) {
      this.x = x;
      this.y = y;
}
myClass.prototype = {
      toString: function() {
            return this.x + " " + this.y;
      }
}
myClass.prototype.constructor = myClass;
var anotherClass = function(x, y, width, height) {
      myClass.call(this, x, y);
      this.height = height;
      this.width = width;
}
var anotherClass.prototype = Object.create(myClass.prototype);
anotherClass.prototype.constructor = anotherClass;

For explanation of inheritance in ES5 refer this post.

There are more other features of ES6 like arrow function which makes closures hell easy, extended libraries and etc which we will cover shortly. Till then keep exploring.

Drop comments for any doubts.

Tuesday 1 March 2016

JavaScript Properties


In this post, we will talk about JavaScript properties, what is inheritance and enumerability.
There are 3 attributes of object's property: writable, enumerable and configurable. Earlier in this post we have seen how object can be created and initialized at the same time like this:

var child = Object.create({a: "Parent Property"}, {
      foo: { writable: true, configurable: true, value: "Everything is weird." }
})

Here, foo is property of child object and it has writable and configurable attribute set. If writable is true, that property can be altered later else not. If configurable is true, that property can be deleted using delete operator else not. And finally if enumerable is true, property will be iterated using for..in loop in it's child objects.

Accessing Properties


Properties can be accessed through its own definition or from its prototype chain.If you are accessing a property from any object than first, object's definition will be searched, if property is not available over there then object's immediate prototype is searched, if not even available there too then prototype's prototype is searched. The search goes on until property is found or up to the highest prototype from prototype chain. But there are some methods defined if you want to iterate only object's own property or all the properties from prototype chain or enumerable properties etc.

Iterating all own properties


var obj = {
      a: "Property of obj"
}
Object.getOwnPropertyNames(obj);
obj.hasOwnProperty(a);
Object.getOwnPropertyDescriptor(obj, a);
obj.b = "Another Property";
obj[c] = "One more Property";
delete obj.c;
delete obj[b];
Object.defineProperty(obj, "foo", { enumerable: true, writable: true, configurable: false, value: "Awesome!" });

Above methods will be used for iterating/accessing all the properties defined by object itself and not inherited from its prototype.

Iterating own enumerable properties


Object.keys(obj);

Above method will be used for iterating all the enumerable properties defined in object defination itself.

Enumerable Inherited Properties


for(var key in obj) {
      console.log(key);
}

All object's properties and enumerable inherited properties.

All Inherited Properties


propName in obj;
obj.propName;
obj[propName];
Using above method, all properties can be accessed.

This was very small post which covered very simple topic. I hope you like it. Please drop your comments.