Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

41 Commits

Repository files navigation

Arrow Functions

A short hand notation for function(), but it does not bind this.

letevens=[1,2,3,4,5,6,7,8,9];letfives=[];letodds=evens.map(v=>v+1);letnums=evens.map((v,i)=>v+i);letpairs=evens.map(v=>({even: v,odd: v+1}));nums.forEach(v=>{if(v%5===0){fives.push(v);}});console.log(odds);console.log(nums);

How does this work?

letobj={name: "Name",arrowGetName: ()=>this.name,regularGetName: function(){returnthis.name},arrowGetThis: ()=>this,regularGetThis: function(){returnthis}};console.log(this.name);console.log(obj.arrowGetName());console.log(obj.arrowGetThis());console.log(this);console.log(obj.regularGetName());console.log(obj.regularGetThis());

Classes

As we know them from "real" languages. Syntactic sugar on top of prototype-inheritence.

classPerson{constructor(name,age){this.name=name;this.age=age;}}console.log(newPerson("Ivan Ivanov",19));

Enhanced Object Literals

vartheProtoObj={toString: function(){return"The prototype toString";}}varhandler=()=>"handler";varobj={// __proto____proto__: theProtoObj,// Shorthand for ‘handler: handler’
handler,// MethodstoString(){// Super callsreturn"d "+super.toString();},// Computed (dynamic) property names["prop_"+(()=>42)()]: 42};console.log(obj.handler);console.log(obj.handler());console.log(obj.toString());console.log(obj.prop_42);

String interpolation

Nice syntax for string interpolation

varname="Ivan Ivanov";vartime="today";varmultiLine=`ThisLineSpans MultipleLines`console.log(`Hello ${name},how are you ${time}?`);console.log(multiLine);

Destructuring

var[a,,b]=[1,2,3];console.log(a);console.log(b);

Objects can be destructured as well.

varnodes=()=>{return{op: "a",lhs: "b",rhs: "c"};};var{op: a,lhs: b,rhs: c}=nodes();console.log(a);console.log(b);console.log(c);

Using Shorthand notation.

varnodes=()=>{return{lhs: "a",op: "b",rhs: "c"};};// binds `op`, `lhs` and `rhs` in scopevar{ op, lhs, rhs }=nodes();console.log(op);console.log(lhs);console.log(rhs);

Can be used in parameter position

functiong({name: x}){returnx;}functionm({ name }){returnname;}console.log(g({name: 5}));console.log(m({name: 5}));

Fail-soft destructuring

var[a]=[];var[b=1]=[];varc=[];console.log(a);console.log(b);console.log(c);

Default

functionf(x,y=12){returnx+y;}console.log(f(3));

Spread

  • In functions
functionf(x,y,z){returnx+y+z;}console.log(f(...[1,2,3]));
  • In arrays
varparts=["shoulders","knees"];varlyrics=["head", ...parts,"and","toes"];console.log(lyrics);

Spread + Object Literals

We can do cool stuff with this in object creations.

let{ x, y, ...z}={x: 1,y: 2,a: 3,b: 4};console.log(x);console.log(y);console.log(z);letn={ x, y, ...z};console.log(n);console.log(obj);

Sadly it is not support yet npm install --save-dev babel-plugin-transform-object-rest-spread

Rest

We can allow unlimited params to function by using the rest operator.

functiondemo(part1, ...part2){return{ part1, part2 }}console.log(demo(1,2,3,4,5,6).part1);console.log(demo(1,2,3,4,5,6).part2);

Let

let is the new var. As it has "sane" bindings.

{varglobalVar="from demo1"}{letglobalLet="from demo2";}console.log(globalVar);console.log(globalLet);

However, it does not assign anything to window

letme="go";// globally scopedvari="able";// globally scopedconsole.log(window.me);console.log(window.i);

It is not possible to redeclare a variable using let

letme="foo";letme="bar";console.log(me);
varme="foo";varme="bar";console.log(me);

Const

const is for read only variables

consta="b";a="a";console.log(a);

It should be noted that const objects can still be mutated.

consta={a: "a"};a.a="b";console.log(a);console.log(a.a);

for..of

New type of iterators with an alternative to the for..in. It returns the value instead of the keys.

letlist=[1,2,3];console.log(list);for(letiinlist){console.log(i);}
letlist=[1,2,3];console.log(list);for(letioflist){console.log(i);}

Iterators

The iterator is a more dynamic type than arrays.

letinfinite={[Symbol.iterator](){letc=0;return{next(){c++;return{done: false,value: c}}}}}console.log("start");for(varnofinfinite){// truncate the sequence at 1000if(n>10)break;console.log(n);}

Generators

Generators create iterators, and are more dynamic than iterators. They do not have to keep track of state in the same manner and does not support the concept of done.

varinfinity={[Symbol.iterator]: function*(){varc=1;for(;;){yieldc++;}}}console.log("start");for(varnofinfinity){if(n>10){break;}console.log(n);}

An example of yield*

function*anotherGenerator(i){yieldi+1;yieldi+2;yieldi+3;}function*generator(i){yieldi;yield*anotherGenerator(i);yieldi+10;}vargen=generator(10);console.log(gen.next().value);console.log(gen.next().value);console.log(gen.next().value);console.log(gen.next().value);console.log(gen.next().value);

Unicode

EcmaScript 6 provides better support for Unicode.

varregex=newRegExp("\u{61}","u");console.log(regex.unicode);console.log("\uD842\uDFD7");console.log("\uD842\uDFD7".codePointAt());

Modules & Module Loaders

Native support for modules.

importdefaultMemberfrom"module-name";import*asnamefrom"module-name";import{member}from"module-name";import{memberasalias}from"module-name";import{member1,member2}from"module-name";import{member1,member2asalias2,[...]}from"module-name";importdefaultMember,{member[,[...]]}from"module-name";importdefaultMember,*asnamefrom"module-name";import"module-name";
export{name1,name2,,nameN};export{variable1asname1,variable2asname2,,nameN};exportletname1,name2,,nameN;// also varexportletname1=,name2=,,nameN;// also var, constexportexpression;exportdefaultexpression;exportdefaultfunction(){}// also class, function*exportdefaultfunctionname1(){}// also class, function*export{name1asdefault,};export*from;export{name1,name2,,nameN}from;export{import1asname1,import2asname2,,nameN}from;

ImportExport

Set

Sets as in the mathematical counterpart where all items are unique. For people who know SQL this is equivalent to distinct.

varset=newSet();set.add("Potato").add("Tomato").add("Tomato");console.log(set.size);console.log(set.has("Tomato"));for(varitemofset){console.log(item);}

Set

WeakSet

The WeakSet object lets you store weakly held objects in a collection. Objects without an reference will be garbage collected.

varitem={a:"Potato"};varset=newWeakSet();set.add({a:"Potato"}).add(item).add({a:"Tomato"}).add({a:"Tomato"});console.log(set.size);console.log(set.has({a:"Tomato"}));console.log(set.has(item));for(letitemofset){console.log(item);}

WeakSet

Map

Maps, also known as dictonaries.

varmap=newMap();map.set("Potato",12);map.set("Tomato",34);console.log(map.get("Potato"))for(letitemofmap){console.log(item);}for(letiteminmap){console.log(item);}

Other types than strings can be used.

varmap=newMap();varkey={a: "a"};map.set(key,12);console.log(map.get(key));console.log(map.get({a: "a"}));

Map

WeakMap

Uses objects for keys, and only keeps weak reference to the keys.

varwm=newWeakMap();varo1={};varo2={};varo3={};wm.set(o1,1);wm.set(o2,2);wm.set(o3,{a: "a"});wm.set({},4);console.log(wm.get(o2));console.log(wm.has({}));deleteo2;console.log(wm.get(o3));for(letiteminwm){console.log(item);}for(letitemofwm){console.log(item);}

WeakMap

Proxies

Proxies can be used to alter objects behavoir. It allows us to define traps.

varobj=functionProfanityGenerator(){return{words: "Horrible words"}}();varhandler=functionCensoringHandler(){return{get: function(target,key){returntarget[key].replace("Horrible","Nice");},}}();varproxy=newProxy(obj,handler);console.log(proxy.words);

Proxies

Symbols

Symbols are a new type. Can be used to create anomymous properties.

vartypeSymbol=Symbol("type");classPet{constructor(type){this[typeSymbol]=type;}getType(){returnthis[typeSymbol];}}vara=newPet("dog");console.log(a.getType());console.log(Object.getOwnPropertyNames(a));console.log(Symbol("a")===Symbol("a"));

More info

Inheritable Built-ins

We can now inherit from native classes.

classCustomArrayextendsArray{}vara=newCustomArray();a[0]=2;console.log(a[0]);

It is not possible to override the getter function without using Proxies of arrays.

New Library

Various new methods and constants.

console.log(Number.EPSILON);console.log(Number.isInteger(Infinity));console.log(Number.isNaN("NaN"));console.log(Math.acosh(3));console.log(Math.hypot(3,4));console.log(Math.imul(Math.pow(2,32)-1,Math.pow(2,32)-2));console.log("abcde".includes("cd"));console.log("abc".repeat(3));console.log(Array.of(1,2,3));console.log([0,0,0].fill(7,1));console.log([1,2,3].find(x=>x==3));console.log([1,2,3].findIndex(x=>x==2));console.log([1,2,3,4,5].copyWithin(3,0));console.log(["a","b","c"].entries());console.log(["a","b","c"].keys());console.log(["a","b","c"].values());console.log(Object.assign({},{origin: newPoint(0,0)}));

Documentation:Number, Math, Array.from, Array.of, Array.prototype.copyWithin, Object.assign

Binary and Octal

Literals for binary and octal numbering.

console.log(0b11111);console.log(0o2342);console.log(0xff);// also in es5

Promises

The bread and butter for async programing.

varp1=newPromise((resolve,reject)=>{setTimeout(()=>resolve("1"),101);});varp2=newPromise((resolve,reject)=>{setTimeout(()=>resolve("2"),100);});Promise.race([p1,p2]).then((res)=>{console.log(res);});Promise.all([p1,p2]).then((res)=>{console.log(res);});

Quick Promise

Need a quick always resolved promise?

varp1=Promise.resolve("1");varp2=Promise.reject("2");Promise.race([p1,p2]).then((res)=>{console.log(res);});

Fail fast

If a promise fails all and race will reject as well.

varp1=newPromise((resolve,reject)=>{setTimeout(()=>resolve("1"),1001);});varp2=newPromise((resolve,reject)=>{setTimeout(()=>reject("2"),1);});Promise.race([p1,p2]).then((res)=>{console.log("success"+res);},res=>{console.log("error "+res);});Promise.all([p1,p2]).then((res)=>{console.log("success"+res);},res=>{console.log("error "+res);});

More Info

Reflect

New type of meta programming with new API for existing and also few new methods.

varz={w: "Super Hello"};vary={x: "hello",__proto__: z};console.log(Reflect.getOwnPropertyDescriptor(y,"x"));console.log(Reflect.has(y,"w"));console.log(Reflect.ownKeys(y,"w"));console.log(Reflect.has(y,"x"));console.log(Reflect.deleteProperty(y,"x"));console.log(Reflect.has(y,"x"));

Tail Call Optimization

EcmaScript 6 should fix ensure tail calls does not generate stack overflow. (Not all implementations work).

functionfactorial(n,acc=1){if(n<=1){returnacc;}returnfactorial(n-1,n*acc);}console.log(factorial(10));console.log(factorial(100));console.log(factorial(1000));console.log(factorial(10000));console.log(factorial(100000));console.log(factorial(1000000));