Arrows
A function shorthand that binds this
value.
Arrow functions are always anonymous.
// // Basic syntax:
// (param1, param2, paramN) => { statements }
// (param1, param2, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one argument:
// singleParam => { statements }
// singleParam => expression
// A function with no arguments requires parentheses:
// () => { statements }
// Advanced:
// Wrap an object literal expression in parentheses
// params => ({foo: bar})
// Rest parameters are supported
// (param1, param2, ...rest) => { statements }
var names = [
{
first : ' john ' ,
last : ' doe '
},
{
first : ' harry ' ,
last : ' potter '
},
{
first : ' wee ' ,
last : ' kee '
}
];
names . map ( name => name . first + name . last );
classes: does not introduce a new way rather is a sugar syntax
A difference between function declarations and class declarations
is that function declarations are hoisted and class declarations are not.
You first need to declare your class and then access it,
otherwise code like the following will throw a ReferenceError:
var p = new Polygon (); // ReferenceError
class Polygon {
constructor ( height , width ) {
this . height = height ;
this . width = width ;
}
// A class can also define a property with get and set to encapsulate a field.
get area () {
return this . calcArea ()
}
calcArea () {
return this . height * this . width ;
}
static distance ( a , b ) {
console . log ( ' I am a static function ' );
console . log ( ' I do not give shit about instances ' );
}
}
Tell me about inheritance
class Cat {
constructor ( name ) {
this . name = name ;
}
speak () {
console . log ( this . name + ' makes a noise. ' );
}
}
class Tiger extends Cat {
speak () {
super . speak ();
console . log ( this . name + ' roars. ' );
}
}
var d = new Tiger ( ' Simba ' ); // Tiger {name: "Simba"}
console . log ( d ); // Simba makes a noise.
console . log ( d . speak ()); // Simba roars.
Enhanced Object Literals
var theProtoObj = {
name : ' whatever ' ,
age : - 1
};
var handler = function () {};
var obj = {
// __proto__
__proto__ : theProtoObj ,
// Shorthand for ‘handler: handler’
handler ,
// Methods
toString () {
// Super calls
return " d " + super . toString ();
},
// Computed (dynamic) property names
[ ' prop_ ' + (() => 42 )() ]: 42
};
Template Strings
var name = " Bob " , time = " today " ;
// and even this is possible
console . log ( `Hello ${ name } , how
are
you ${ time } ?` );
Destructuring
var foo = [ " one " , " two " , " three " ];
var [ one , two , three ] = foo ;
var a , b ;
[ a , b ] = [ 1 , 2 ];
multiple returns
var func = function () {
return [ 1 , 2 ];
};
var [ a , b ] = func ();
var { p , q } = { p : 42 , q : true };
console . log ( p ); // 42
console . log ( q ); // true
// Assign new variable names
var { p : foo , q : bar } = { p : 42 , q : true };
console . log ( foo ); // 42
console . log ( bar ); // true
Default
function f ( x , y = 12 ) {
// y is 12 if not passed (or passed as undefined)
return x + y ;
}
f ( 3 ); // 15;
Rest Parameters
function f ( x , ... y ) {
// y is an Array
return x * y . length ;
}
f ( 3 , " hello " , true ); // 6;
Symbol:
A unique and immutable data type and may be used as an identifier
for object properties. It is an implicit object wrapper for the symbol
primitive data type.
var fooSym = Symbol ( ' foo ' );
var myObj = {};
myObj [ ' foo ' ] = ' bar ' ;
myObj [ fooSym ] = ' baz ' ;
Object . keys ( myObj ); // -> [ 'foo' ]
Object . getOwnPropertyNames ( myObj ); // -> [ 'foo' ]
Object . getOwnPropertySymbols ( myObj ); // -> [ Symbol(foo) ]
assert ( Object . getOwnPropertySymbols ( myObj )[ 0 ] === fooSym );
Symbol.for: not unique
There is also another way to make Symbols - Symbol.for()
This method creates a Symbol in a “global Symbol registry”.
var myObj = {};
var fooSym = Symbol . for ( ' foo ' );
var otherSym = Symbol . for ( ' foo ' );
myObj [ fooSym ] = ' baz ' ;
myObj [ otherSym ] = ' bing ' ;
assert ( fooSym === otherSym );
assert ( myObj [ fooSym ] === ' bing ' );
assert ( myObj [ otherSym ] === ' bing ' );
Symbol: Usage
var Pet = ( function () {
var typeSymbol = Symbol ( ' type ' );
function Pet ( type ) {
this [ typeSymbol ] = type ;
}
Pet . prototype . getType = function (){
return this [ typeSymbol ];
}
return Pet ;
}());
var a = new Pet ( ' dog ' );
a . getType (); // dog
a . type = null ; // stays private
a . getType (); // dog
Iterator and Iterable
let arr = [ ' a ' , ' b ' , ' c ' ]; // array is iterable
let iter = arr [ Symbol . iterator ](); // iter is iterator
iter . next () // { value: 'a', done: false }
iter . next () // { value: 'b', done: false }
iter . next () // { value: 'c', done: false }
iter . next () // { value: undefined, done: true }
// By default, objects are not iterable
// but we can try
let a = { name : ' hmmm ' , age : 23 , address : { city : ' ny ' , state : ' bihar ' }};
// add iterator function
a [ Symbol . iterator ] = function () {
var nextIndex = 0 ;
var keys = Object . keys ( this );
var self = this ;
return {
next : function (){
return nextIndex < keys . length ?
{ value : self [ keys [ nextIndex ++ ]], done : false } :
{ done : true };
}
};
};
var it = a [ Symbol . iterator ]();
console . log ( it . next ());
console . log ( it . next ());
console . log ( it . next ());
console . log ( it . next ());
For - of
for ( let x of [ ' a ' , ' b ' ]) {
console . log ( x );
}
// Output:
// 'a'
// 'b'
let map = new Map (). set ( ' a ' , 1 ). set ( ' b ' , 2 );
for ( let pair of map ) {
console . log ( pair );
}
// Output:
// ['a', 1]
// ['b', 2]
for ( let x of {}) { // TypeError
console . log ( x );
}
Sets
var s = new Set ();
s . add ( " hello " ). add ( " goodbye " ). add ( " hello " );
s . size === 2 ;
s . has ( " hello " ) === true ;
Maps
var m = new Map ();
m . set ( " hello " , 42 );
m . set ( s , 34 );
m . get ( s ) == 34 ;
WeakMaps
// provides leak-free object-key’d side tables.
var wm = new WeakMap ();
wm . set ( s , { extra : 42 });
wm . size === undefined
Weak Sets
var ws = new WeakSet ();
ws . add ({ data : 42 });
// Because the added object has no other references,
// it will not be held in the set.
Newly added APIs
' hello ' . startsWith ( ' hell ' ) // true
' hello ' . endsWith ( ' ello ' ) // true
' hello ' . includes ( ' ell ' ) // true
' doo ' . repeat ( 3 ) // 'doo doo doo '
Array.from
// Convert array-like structure to array
let lis = document . querySelectorAll ( ' ul.fancy li ' );
Array . from ( lis ). forEach ( function ( li ) {
console . log ( node );
});
Array . from ([ ' a ' , ' b ' ]. keys ()) // [ 0, 1 ]
Array . from ([ ' a ' , ' b ' ]. values ()) // [ 'a', 'b' ]
Array . from ([ ' a ' , ' b ' ]. entries ()) // [ [ 0, 'a' ], [ 1, 'b' ] ]
Now the much awaited - Generators
They are mystical, nobody have seen them but some people say that they looks like a function though do not
behave like them. Well, that’s strange. Let me tell you the long story short. With ES6 generators, we
have a different kind of function, which may be paused in the middle, one or many times, and resumed later,
allowing other code to run during these paused periods. So they kind of use yield
keyword to stop where ever
they want ( like a debugger
in Chrome ). Let’s see that in action.
function * foo () {
var x = 1 + ( yield " foo " );
console . log ( x );
}
let it = foo ();
it . next (); // reutrns { done: false, value: "foo" }
it . next (); // prints x as NaN and returns { done: true, value: undefined }
// now once all the yields are done
it . next (); // returns { done: true, value: undefined }
function * foo () {
yield 1 ;
yield 2 ;
yield 3 ;
yield 4 ;
yield 5 ;
}
let it = foo ();
it . next (); // { value:1, done:false }
it . next (); // { value:2, done:false }
it . next (); // { value:3, done:false }
it . next (); // { value:4, done:false }
it . next (); // { value:5, done:false }
it . next (); // { value:undefined, done:true }
Till now we have only seen Generators
yielding something everytime, but there is more to it - you can talk too.
function * foo ( x ) {
var y = 2 * ( yield ( x + 1 ));
var z = yield ( y / 3 );
return ( x + y + z );
}
var it = foo ( 5 );
// note: not sending anything into `next()` here
it . next (); // { value:6, done:false }
it . next ( 12 ); // { value:8, done:false }
it . next ( 13 ); // { value:42, done:true }