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());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));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);Nice syntax for string interpolation
varname="Ivan Ivanov";vartime="today";varmultiLine=`ThisLineSpans MultipleLines`console.log(`Hello ${name},how are you ${time}?`);console.log(multiLine);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);functionf(x,y=12){returnx+y;}console.log(f(3));- 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);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
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 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 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);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);}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 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);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());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…;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);}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);}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"}));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);}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);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"));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.
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
Literals for binary and octal numbering.
console.log(0b11111);console.log(0o2342);console.log(0xff);// also in es5The 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);});Need a quick always resolved promise?
varp1=Promise.resolve("1");varp2=Promise.reject("2");Promise.race([p1,p2]).then((res)=>{console.log(res);});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);});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"));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));