background image
background image

1.

Introduction

2.

let+const

3.

arrowfunctions

4.

default+rest+spread

5.

destructuring

6.

strings

7.

iterators

8.

generators

9.

classesandinheritance

10.

modules

11.

promises

12.

set,map,weak

TableofContents

es6-guide

2

background image

ECMAScript6(ES6)guide

CHECK

SUMMARY

TOSEETABLEOFCONTENT

Iwanttosharewithyousomethoughts,snippetsofcodeandtellyoualittleabouttheupcomingES6.It’smyownroadto

knowitbeforeitwillbeastandard.

YoumighthavenoticedaboutES6alotlately.ThisisbecausethestandardistargetingratificationinJune2015.

Seedraft-

ECMAScript2015

ECMAScript2015isasignificantupdatetothelanguage.Previous(ES5)wasstandardizedin2009.Frameworkslike

AngularJS,Aurelia,ReactJS,Ionicstartusingittoday.

ES6includesalotofnewfeatures:

arrows

classes

enhancedobjectliterals

templatestrings

destructuring

default+rest+spread

let+const

iterators+for..of

generators

unicode

modules

moduleloaders

map+set+weakmap+weakset

proxies

symbols

subclassablebuilt-ins

promises

math+number+string+objectAPIs

binaryandoctalliterals

reflectapi

ES6-guide

es6-guide

3

Introduction

background image

tailcalls

Iwilltrytodescribeeachoftheseinthenextstories,sostayupdated.

Thankstotheuseoftranspilers(Babel,Traceurandothers)wecanactuallyuseitrightnowuntilbrowsersfullycatchup.

Browsersupportmatrix

ES6ReplinChromeDevlTools-

ScratchJS

Futureisbright.

Peoplefromthecommunitydenouncedthesewords.Ihaveonlyonetoadd:wecanhandleiteasily!

es6-guide

4

Introduction

background image

FirsttopicaboutECMAScript2015islet+const.IfyouarefamiliarwithJavaScript,youhaveprobablyknowntheterm:

scope.Ifyouarenotthatlucky,don'tworryaboutit.I'llexplainthatinafewwordsbelow.

WhyImentionedsomethingaboutJavaScriptscope?Thisisbecauseletandconsthaveaverystrongconnectionwith

thatword.Firstly,imagineandoldway(andstillvalid)todeclareanewvariableinyourJScodeusingES5:

//ES5

var

a=

1

;

if

(

1

===a){

var

b=

2

;

}

for

(

var

c=

0

;c<

3

;c++){

//…

}

function

letsDeclareAnotherOne

()

{

var

d=

4

;

}

console

.log(a);

//1

console

.log(b);

//2

console

.log(c);

//3

console

.log(d);

//ReferenceError:disnotdefined

//window

console

.log(

window

.a);

//1

console

.log(

window

.b);

//2

console

.log(

window

.c);

//3

console

.log(

window

.d);

//undefined

1. Wecanseethatvariableaisdeclaredasglobal.Nothingsurprising.

2. Variablebisinsideanifblock,butinJavaScriptitdoesn'tcreateanewscope.Ifyouarefamiliarwithother

languages,youcanbedisappointed,butthisisJavaScriptanditworksasyousee.

3. Thenextstatementisaforloop.Cvariableisdeclaredinthisforloop,butalsointheglobalscope.

4. Untilvariabledisdeclaredinhisownscope.It'sinsideafunctionandonlyfunctioncreatesnewscopes.

VariablesinJavaScriptarehoistedtothetop!

HoistingisJavaScript'sdefaultbehaviorofmovingalldeclarationstothetopofthecurrentscope(tothetopofthe

currentscriptorthecurrentfunction).

InJavaScript,avariablecanbedeclaredafterithasbeenused.Inotherwords-avariablecanbeusedbeforeithasbeen

declared!

Onemorerule,moreaware:JavaScriptonlyhoistsdeclarations,notinitialization.

//scopeandvariablehoisting

var

n=

1

;

(

function

()

{

console

.log(n);

var

n=

2

;

let+const

es6-guide

5

let+const

background image

console

.log(n);

})();

console

.log(n);

Let'slookforthenewkeywordsinJavaScriptECMAScript2015:letandconst.

Wecanimaginethatletisanewvarstatement.Whatisthedifference?letisblockscoped.Let'sseeanexample:

//ES6—let

let

a=

1

;

if

(

1

===a){

let

b=

2

;

}

for

(

let

c=

0

;c<

3

;c++){

//…

}

function

letsDeclareAnotherOne

()

{

let

d=

4

;

}

console

.log(a);

//1

console

.log(b);

//ReferenceError:bisnotdefined

console

.log(c);

//ReferenceError:cisnotdefined

console

.log(d);

//ReferenceError:disnotdefined

//window

console

.log(

window

.a);

//1

console

.log(

window

.b);

//undefined

console

.log(

window

.c);

//undefined

console

.log(

window

.d);

//undefined

Aswecansee,thistimeonlyvariableaisdeclaredasaglobal.letgivesusawaytodeclareblockscopedvariables,which

isundefinedoutsideit.

IuseChrome(stableversion)with#enable-javascript-harmonyflagenabled.Visitchrome://flags/#enable-

javascript-harmony,enablethisflag,restartChromeandyouwillgetmanynewfeatures.

YoucanalsouseBabelJSreplorTraceurreplandcompareresults.

constissingle-assignmentandlikealet,block-scopeddeclaration.

//ES6const

{

const

PI=

3.141593

;

PI=

3.14

;

//throws“PI”isread-only

}

console

.log(PI);

//throwsReferenceError:PIisnotdefined

constcannotbereinitialized.ItwillthrowanErrorwhenwetrytoassignanothervalue.

let

const

es6-guide

6

let+const

background image

Let'slookfortheequivalentinES5:

//ES5const

var

PI=(

function

()

{

var

PI=

3.141593

;

return

function

()

{

return

PI;};

})();

es6-guide

7

let+const

background image

AnewsyntacticsugarwhichES6bringsussoon,calledarrowfunctions(alsoknownasafatarrowfunction).It'sashorter

syntaxcomparedtofunctionexpressionsandlexicallybindsthisvalue.

REMEMBER-Arrowfunctionsarealwaysanonymous.

Howdoesitlook?It'sasignature:

([param][,param])=>{

statements

}

param=>expression

(param1,param2)=>{block}

..anditcouldbetranslatedto:

()=>{…}

//noargument

x=>{…}

//oneargument

(x,y)=>{…}

//severalarguments

x=>{

return

x*x}

//block

x=>x*x

//expression,sameasabove

LambdaexpressionsinJavaScript!Cool!

Insteadofwriting:

[

3

,

4

,

5

].map(

function

(n)

{

return

n*n;

});

..youcanwritesomethinglikethis:

[

3

,

4

,

5

].map(n=>n*n);

Awesome.Isn'tit?Thereismore!

Thevalueofthisinsideofthefunctionisdeterminedbywherethearrowfunctionisdefinednotwhereitisused.

Nomorebind,callandapply!Nomore:

var

self=

this

;

arrowfunctions

Syntacticsugar

Fixed"this"=lexical"this"

es6-guide

8

arrowfunctions

background image

Itsolvesamajorpainpoint(frommypointofview)andhastheaddedbonusofimprovingperformancethroughJavaScript

engineoptimizations.

//ES5

function

FancyObject

()

{

var

self=

this

;

self.name=

'FancyObject'

;

setTimeout(

function

()

{

self.name=

'HelloWorld!'

;

},

1000

);

}

//ES6

function

FancyObject

()

{

this

.name=

'FancyObject'

;

setTimeout(()=>{

this

.name=

'HelloWorld!'

;

//properlyreferstoFancyObject

},

1000

);

}

typeofreturnsfunction

instanceofreturnsFunction

It'scannotbeusedasaconstructorandwillthrowanerrorwhenusedwithnew.

Fixedthismeansthatyoucannotchangethevalueofthisinsideofthefunction.Itremainsthesamevalue

throughouttheentirelifecycleofthefunction.

Regularfunctionscanbenamed.

Functionsdeclarationsarehoisted(canbeusedbeforetheyaredeclared).

Thesamefunction

Limitations

es6-guide

9

arrowfunctions

background image

ECMAScript2015functionsmadeasignificantprogress,takingintoaccountyearsofcomplaints.Theresultisanumberof

improvementsthatmakeprogramminginJavaScriptlesserror-proneandmorepowerful.

Let'sseethreenewfeatureswhichgiveusextendedparameterhandling.

It'sasimple,littleadditionthatmakesitmucheasiertohandlefunctionparameters.FunctionsinJavaScriptallowany

numberofparameterstobepassedregardlessofthenumberofdeclaredparametersinthefunctiondefinition.You

probablyknowcommonlyseenpatternincurrentJavaScriptcode:

function

inc

(number,increment)

{

//setdefaultto1ifincrementnotpassed

//(orpassedasundefined)

increment=increment||

1

;

return

number+increment;

}

console

.log(inc(

2

,

2

));

//4

console

.log(inc(

2

));

//3

ThelogicalORoperator(||)alwaysreturnsthesecondoperandwhenthefirstisfalsy.

ES6givesusawaytosetdefaultfunctionparameters.Anyparameterswithadefaultvalueareconsideredtobeoptional.

ES6versionofincfunctionlookslikethis:

function

inc

(number,increment=1)

{

return

number+increment;

}

console

.log(inc(

2

,

2

));

//4

console

.log(inc(

2

));

//3

Youcanalsosetdefaultvaluestoparametersthatappearbeforeargumentswithoutdefaultvalues:

function

sum

(a,b=2,c)

{

return

a+b+c;

}

console

.log(sum(

1

,

5

,

10

));

//16->b===5

console

.log(sum(

1

,

undefined

,

10

));

//13->basdefault

Youcanevenexecuteafunctiontosetdefaultparameter.It'snotrestrictedtoprimitivevalues.

functiongetDefaultIncrement(){

return1;

}

functioninc(number,increment=getDefaultIncrement()){

returnnumber+increment;

}

default+rest+spread

default

es6-guide

10

default+rest+spread

background image

console.log(inc(2,2));//4

console.log(inc(2));//3

Let'srewritesumfunctiontohandleallargumentspassedtoit(withoutvalidation-justtobeclear).IfwewanttouseES5,

weprobablyalsowanttouseargumentsobject.

function

sum

()

{

var

numbers=

Array

.prototype.slice.call(

arguments

),

result=

0

;

numbers.forEach(

function

(number)

{

result+=number;

});

return

result;

}

console

.log(sum(

1

));

//1

console

.log(sum(

1

,

2

,

3

,

4

,

5

));

//15

Butit'snotobviousthatthefunctioniscapableofhandlinganyparameters.Whavetoscanbodyofthefunctionandfind

argumentsobject.

ECMAScript6introducesrestparameterstohelpuswiththisandotherpitfalls.

arguments-containsallparametersincludingnamedparameters

Restparametersareindicatedbythreedotsprecedingaparameter.Namedparameterbecomesanarraywhichcontain

therestoftheparameters.

sumfunctioncanberewrittenusingES6syntax:

function

sum

(…numbers)

{

var

result=

0

;

numbers.forEach(

function

(number)

{

result+=number;

});

return

result;

}

console

.log(sum(

1

));

//1

console

.log(sum(

1

,

2

,

3

,

4

,

5

));

//15

Restriction:noothernamedargumentscanfollowinthefunctiondeclaration.

function

sum

(…numbers,last)

{

//causesasyntaxerror

var

result=

0

;

numbers.forEach(

function

(number)

{

result+=number;

});

return

result;

}

Thespreadiscloselyrelatedtorestparameters,becauseof(threedots)notation.Itallowstosplitanarraytosingle

rest

spread

es6-guide

11

default+rest+spread

background image

argumentswhicharepassedtothefunctionasseparatearguments.

Let'sdefineoursumfunctionanpassspreadtoit:

function

sum

(a,b,c)

{

return

a+b+c;

}

var

args=[

1

,

2

,

3

];

console

.log(sum(…args));

//6

ES5equivalentis:

function

sum

(a,b,c)

{

return

a+b+c;

}

var

args=[

1

,

2

,

3

];

console

.log(sum.apply(

undefined

,args));

//6

Insteadusinganapplyfunction,wecanjusttype…argsandpassallarrayargumentseparately.

Wecanalsomixstandardargumentswithspreadoperator:

function

sum

(a,b,c)

{

return

a+b+c;

}

var

args=[

1

,

2

];

console

.log(sum(…args,

3

));

//6

Theresultisthesame.Firsttwoargumentsarefromargsarray,andthelastpassedargumentis3.

es6-guide

12

default+rest+spread

background image

DestructuringisonemorelittleadditiontotheupcomingJavaScriptstandard,whichhelpsuswritecodemoreflexiblyand

effectively.

Itallowsbindingusingpatternmatching.Wecanuseitformatchingarraysandobjects.It'ssimilartostandardobjectlook

upandreturnsundefinedwhenvalueisnotfound.

Todayit'scommontoseethecodesuchasthis.

//ES5

var

point=[

1

,

2

];

var

xVal=point[

0

],

yVal=point[

1

];

console

.log(xVal);

//1

console

.log(yVal);

//2

ES6givesusdestructuringofarraysintoindividualvariablesduringassignmentwhichisintuitiveandflexible.

//ES6

let

point=[

1

,

2

];

let

[xVal,yVal]=point;

console

.log(xVal);

//1

console

.log(yVal);

//2

//..andreverse!

[xVal,yVal]=[yVal,xVal];

console

.log(xVal);

//2

console

.log(yVal);

//1

Wecanevenomitsomevalues..

let

threeD=[

1

,

2

,

3

];

let

[a,,c]=threeD;

console

.log(a);

//1

console

.log(c);

//3

..andhavenestedarraydestructuring.

let

nested=[

1

,[

2

,

3

],

4

];

let

[a,[b],d]=nested;

console

.log(a);

//1

console

.log(b);

//2

console

.log(d);

//4

destructuring

arrays

objects

es6-guide

13

destructuring

background image

Aswellasthearraysyntax,ES6alsohastheabilitytodestructureobjects.Itusesanobjectliteralontheleftsideofan

assignmentoperation.Objectpatternisverysimilartoarraypatternseenabove.Let'ssee:

let

point={

x:

1

,

y:

2

};

let

{x:a,y:b}=point;

console

.log(a);

//1

console

.log(b);

//2

Itsupportsnestedobjectaswellasarraypattern.

let

point={

x:

1

,

y:

2

,

z:{

one:

3

,

two:

4

}

};

let

{x:a,y:b,z:{one:c,two:d}}=point;

console

.log(a);

//1

console

.log(b);

//2

console

.log(c);

//3

console

.log(d);

//4

Wecanalsomixobjectsandarraystogetherandusetheirsliterals.

let

mixed={

one:

1

,

two:

2

,

values:[

3

,

4

,

5

]

};

let

{one:a,two:b,values:[c,,e]}=mixed;

console

.log(a);

//1

console

.log(b);

//2

console

.log(c);

//3

console

.log(e);

//5

ButIthinkthemostinterestingisthatweareabletousefunctionswhichreturndestructuringassignment.

function

mixed

()

{

return

{

one:

1

,

two:

2

,

values:[

3

,

4

,

5

]

};

}

let

{one:a,two:b,values:[c,,e]}=mixed();

console

.log(a);

//1

console

.log(b);

//2

console

.log(c);

//3

console

.log(e);

//5

mixed

es6-guide

14

destructuring

background image

Thesameresult!Itgivesusalotofpossibilitiestouseitinourcode.

Ifthevalueofadestructuringassignmentisn'tmatch,itevaluatestoundefined.

let

point={

x:

1

};

let

{x:a,y:b}=point;

console

.log(a);

//1

console

.log(b);

//undefined

Ifwetrytoomitvar,letorconst,itwillthrowanerror,becauseblockcodecan'tbedestructuringassignment.

let

point={

x:

1

};

{x:a}=point;

//throwserror

Wehavetowrapitinparentheses.Justthat☺

let

point={

x:

1

};

({x:a}=point);

console

.log(a);

//1

attention!

es6-guide

15

destructuring

background image

IgonnashowyouacoupleofchangestostringsinJavaScript,whichwillbeavailablewhenES6comes.Asyntacticsugar,

whichcouldbehelpfulindailywork.

First,astringinterpolation.Yep,templatestrings(finally)supportstringinterpolation.ES6bringsusalsosupportfor

multi-linesyntaxandrawliterals.

let

x=

1

;

let

y=

2

;

let

sumTpl=`${x}+${y}=${x+y}`;

console

.log(sumTpl);

//1+2=3

Asyoucansee,wecaninjectvaluestostringbyusing${value}syntax.Anotherthingtoconsiderisgraveaccent-achar

underthetilde(~)onakeyboard.Atemplateliteralstringmustbewrappedbyit,toworkproperly.

Theexampleaboveisanequivalent(inES5)tosimply(Babelversion):

var

x=

1

;

var

y=

2

;

var

sumTpl=

""

+x+

"+"

+y+

"="

+(x+y);

console

.log(sumTpl);

//1+2=3

Thisfeatureisveryusefulandalmostremovestheneedforatemplatesystem.

Templatestringsprovidealsomulti-linesyntax,whichisnotlegalinES5andearlier.

let

types=`

Number

String

Array

Object

`;

console

.log(types);

//Number

//String

//Array

//Object

ES5equivalent:

var

types=

"Number\nString\nArray\nObject"

;

console

.log(types);

//Number

//String

//Array

//Object

Thelastthingisaccesstherawtemplatestringcontentwherebackslashesarenotinterpreted.Wedon'thaveequivalent

inES5here.

let

interpreted=

'raw\nstring'

;

strings

templatestrings

es6-guide

16

strings

background image

let

esaped=

'raw\\nstring'

;

let

raw=

String

.raw`raw\nstring`;

console

.log(interpreted);

//raw

//string

console

.log(raw===esaped);

//true

ES6givesusfullsupportforUnicodewithinstringsandregularexpressions.It'snon-breakingadditionallowstobuilding

globalapps.

Let'sseeanexample:

let

str=

''

;

console

.log(str.length);

//2

console

.log(str===

'\uD842\uDFB7'

);

//true

Youcanseethatcharacter*representedbytwo16-bitcodeunits.It'sasurrogatepairinwhichwehaveasinglecodepoint

representedbytwocodeunits.Thelengthofthatstringisalso2.

SurrogatepairsareusedinUTF-16torepresentcodepointsaboveU+FFFF.

console

.log(str.charCodeAt(

0

));

//55362

console

.log(str.charCodeAt(

1

));

//57271

ThecharCodeAt()methodreturnsthe16-bitnumberforeachcodeunit.

ES6allowsencodingofstringsinUTF-16.JavaScriptcannowsupportworkwithsurrogatepairs.Itgivesusalsoanew

methodcodePointAt()thatreturnsUnicodecodepointinsteadofUnicodecodeunit.

console

.log(str.codePointAt(

0

));

//134071

console

.log(str.codePointAt(

1

));

//57271

console

.log(str.codePointAt(

0

)===

0x20BB7

);

//true

ItworksthesameascharCodeAt()exceptfornon-BMPcharacters.

BMP-BasicMultilingualPlane-thefirst2^16codepoints.

codePointAt()returnsfullcodepointatthe0position.codePointAt()andcharCodeAt()returnthesamevalueforposition

1.

WecanalsodoareverseoperationwithanothernewmethodaddedtoES6:fromCodePoint().

console

.log(

String

.fromCodePoint(

134071

));

//""

console

.log(

String

.fromCodePoint(

0x20BB7

));

//""

Unicodecodeunitescapesequencesconsistofsixcharacters,namely\uplusfourhexadecimaldigits,and

contributeonecodeunit.

Unicodecodepointescapesequencesconsistoffivetotencharacters,namely\u{1–6hexadecimaldigits},and

extendedsupportforUnicode

es6-guide

17

strings

background image

contributeoneortwocodeunits.

Dealingwiththattwodefinitions,aboveexamplecouldberepresentedbyonecodepointinES6:

//ES6

console.log('\u{20BB7}');//

console.log('\u{20BB7}'==='\uD842\uDFB7');//true

//ES5

console.log('\u20BB7);//7!

console.log('\u20BB7'==='\uD842\uDFB7');//false

InES5wegetanunexpectedresultwhenwetrytomatchonesinglecharacterusingregularexpression.

console

.log(

/^.$/

.test(str));

//false-lengthis2

ES6allowsustousenewRegExpumodetohandlecodepoints.Itissimplyanewuflag(u==Unicode).

console

.log(

/^.$/u

.test(str));

//true

Addinguflagallowstocorrectlymatchthestringbycharactersinsteadofcodeunits.

Stringsareiterablebyusingthefor-ofloopwhichIwillcoverinmoredetailiniteratorsarticlelater.Iwriteaboutitnow

becauseitenumerateUnicodecodepointsandeachmaycompriseoneortwocharacters.

let

str=

'abc\uD842\uDFB7'

;

console

.log(str.length);

//5

for

(

let

cofstr){

console

.log(c);

//a

//b

//c

//

}

WecanalsousespreadoperatortotransformstringintoanarraywithfullUnicodesupport.

let

str=

'abc\uD842\uDFB7'

;

let

chars=[…str];

console

.log(chars);

//['a','b','c','']

repeat(n)-stringrepeatsbyntimes

console

.log(

'abc|'

.repeat(

3

));

//'abc|abc|abc|'

startsWith(str,starts=0):boolean-checkifstringstartswithstr,startingfromstarts

stringsareiterable

newstringmethods

es6-guide

18

strings

background image

console

.log(

'ecmascript'

.startsWith(

'ecma'

));

//true

console

.log(

'ecmascript'

.startsWith(

'script'

,

4

));

//true

endsWith(str,ends=str.length):boolean-checkifstringendswithstr,ends-wherethestringtobecheckedends

console

.log(

'ecmascript'

.endsWith(

'script'

));

//true

console

.log(

'ecmascript'

.endsWith(

'ecma'

,

4

));

//true

includes(str,starts=0):boolean-checkifstringcontainstr,startingfromstarts

console

.log(

'ecmascript'

.includes(

'ecma'

));

//true

console

.log(

'ecmascript'

.includes(

'script'

,

4

));

//true

es6-guide

19

strings

background image

Aniteratorisanobjectwithanextmethodthatreturns{done,value}tuples.

ES6givesusapatternforcreatingcustomiteratorsandithasasimilarimplementationtoJavaIterableor.NET

IEnumerable.Ithasalsobuilt-initerables:String,Array,TypedArray,MapandSet.Aniteratorobjectcanbeanyobject

withanext()method.

Iterableisanobjectwhichhas

Symbol.iterator

methodinside.

Symbolisinturnanuniqueandimmutabledatatypewhichcanbeusedasanidentifierforobjectproperties — no

equivalentinES5.

//Symbol

let

s1=Symbol(

'abc'

);

let

s2=Symbol(

'abc'

);

console

.log(s1!==s2);

//true

console

.log(

typeof

s1);

//'symbol'

let

obj={};

obj[s1]=

'abc'

;

console

.log(obj);

//Object{Symbol(abc):'abc'}

Let'sseeasimpleiteratorwrittenfromscratch,whichallowsustoiteratethroughrandomnumberswhicharedynamically

generatedbynext()method.Afunctionreturningiterableobjecttakeoneargument(items)whichisusedtodetermineif

theiteratorshouldstopandreturnsdone=true.

let

random1_10=

function

(items=1)

{

return

{

[Symbol.iterator](){

let

cur=

0

;

return

{

next(){

let

done=cur===items,

random=

Math

.floor(

Math

.random()*

10

)+

1

;

++cur;

return

{

done:done,

value:random

}

}

}

}

};

};

for

(

let

nofrandom1_10(

5

)){

console

.log(n);

//prints5randomnumbers

}

Everytimefor-ofloopcallnext()method,aniteratorgeneratearandomnumberandreturnsittotheloop.

Iftheiteratorreturnsdone=true,youcanomitvalue,sotheresultwillbe{done:true}

let

random1_10=

function

(items=1)

{

iterators

iterator&iterable

es6-guide

20

iterators

background image

return

{

[Symbol.iterator](){

let

cur=

0

;

return

{

next(){

if

(cur===items){

return

{

done:

true

}

}

++cur;

return

{

done:

false

,

value:

Math

.floor(

Math

.random()*

10

)+

1

}

}

}

}

};

};

for

(

let

nofrandom1_10(

5

)){

console

.log(n);

//prints5randomnumbers

}

ES6hasanewloop — for-of.Itworkswithiterables.Let'slookathissignature:

for

(LETofITERABLE){

CODEBLOCK

}

It'ssimilartofor-inloop,whichcanbeusedtoiteratethroughobjectproperties(plainoldObjects).

ArraysinES6areiterablebydefault,sowefinallycanusefor-offorloopingovertheelements.

const

arr=[

1

,

2

,

3

,

4

,

5

];

for

(

let

itemofarr){

console

.log(item);

//1

//2

//3

//4

//5

}

Insidethefor-ofloop,wecanevenuseabreak,continueandreturn.

const

arr=[

1

,

2

,

3

,

4

,

5

];

for

(

let

itemofarr){

if

(item>

4

){

break

;

}

if

(

0

!==item%

2

){

continue

;

}

console

.log(item);

//2

//4

}

for-ofloop

es6-guide

21

iterators

background image

GeneratorsaresimplysubtypesofIteratorswhichIwroteaboutpreviously.Theyareaspecialkindoffunctionthatcanbe

suspendedandresumed,whichismakingadifferencetoiterators.Generatorsusefunction*andyieldoperatorstowork

theirmagic.

Theyieldoperatorreturnsavaluefromthefunctionandwhenthegeneratorisresumed,executioncontinuesafter

theyield.

Wealsohavetousefunction*(withstarcharacter)insteadofafunctiontoreturnageneratorinstance.

!!!GeneratorshavebeenborrowedfromPythonlanguage.

ThemostmagicalfeatureinES6!

Why?Takealook:

function

*

generator

()

{

yield

1

;

//pause

yield

2

;

//pause

yield

3

;

//pause

yield

'done?'

;

//done

}

let

gen=generator();

//[objectGenerator]

console

.log(gen.next());

//Object{value:1,done:false}

console

.log(gen.next());

//Object{value:2,done:false}

console

.log(gen.next());

//Object{value:3,done:false}

console

.log(gen.next());

//Object{value:'done?',done:false}

console

.log(gen.next());

//Object{value:undefined,done:true}

console

.log(gen.next());

//Object{value:undefined,done:true}

for

(

let

valofgenerator()){

console

.log(val);

//1

//2

//3

//'done?'

}

Asyoucansee,thegeneratorhasfouryieldstatements.Eachreturnsavalue,pausesexecutionandmovestothenext

yieldwhennext()methodiscalled.Callingafunctionproducesanobjectforcontrollinggeneratorexecution,aso-called

generatorobject.

Useissimilartoiterators.Wehavenext()methodasImentionedaboveandwecanevenuseitwithfor-ofloop.

Belowisanexampleofageneratorcalledrandom1_10,whichreturnsrandomnumbersfrom1to10.

function

*

random1_10

()

{

while

(

true

){

yield

Math

.floor(

Math

.random()*

10

)+

1

;

}

}

let

rand=random1_10();

console

.log(rand.next());

console

.log(rand.next());

//…

generators

es6-guide

22

generators

background image

Generatorhasneverendingwhileloop.Itproducesrandomnumberseverytimewhenyoucallnext()method.

ES5implementation:

function

random1_10

()

{

return

{

next:

function

()

{

return

{

value:

Math

.floor(

Math

.random()*

10

)+

1

,

done:

false

};

}

};

}

let

rand=random1_10();

console

.log(rand.next());

console

.log(rand.next());

//…

Wecanalsomixgeneratorstogether:

function

*

random

(max)

{

yield

Math

.floor(

Math

.random()*max)+

1

;

}

function

*

random1_20

()

{

while

(

true

){

yield

*random(

20

);

}

}

let

rand=random1_20();

console

.log(rand.next());

console

.log(rand.next());

//…

random1_20generatorreturnsrandomvaluesfrom1to20.Itusesrandomgeneratorinsidetocreaterandomnumber

eachtimewhenyieldstatementisreached.

es6-guide

23

generators

background image

OOkeywordsisprobablythemostawaitedfeaturesinES6.Classesaresomethinglikeanothersyntacticsugaroverthe

prototype-basedOOpattern.Wenowhaveone,concisewaytomakeclasspatternseasiertouse.

Overtheprototype-basedOOpatterntoensurebackwardscompatibility.

class

Vehicle{

constructor(name,type){

this

.name=name;

this

.type=type;

}

getName(){

return

this

.name;

}

getType(){

return

this

.type;

}

}

let

car=

new

Vehicle(

'Tesla'

,

'car'

);

console

.log(car.getName());

//Tesla

console

.log(car.getType());

//car

It'snaiveexample,butwecanseeanewkeywordsasclassandconstructor.

ES5equivalentcouldbesomethinglikethis:

function

Vehicle

(name,type)

{

this

.name=name;

this

.type=type;

};

Vehicle.prototype.getName=

function

getName

()

{

return

this

.name;

};

Vehicle.prototype.getType=

function

getType

()

{

return

this

.type;

};

var

car=

new

Vehicle(

'Tesla'

,

'car'

);

console

.log(car.getName());

//Tesla

console

.log(car.getType());

//car

Classessupportprototype-basedinheritance,supercalls,instanceandstaticmethodsandconstructors.

It'ssimple.Weinstantiateourclassesthesameway,butlet'saddsome..

classesandinheritance

Overview — anexampleofES6classsyntaxandES5
equivalent

inheritance

es6-guide

24

classesandinheritance

background image

..toitandstartfromES5example:

function

Vehicle

(name,type)

{

this

.name=name;

this

.type=type;

};

Vehicle.prototype.getName=

function

getName

()

{

return

this

.name;

};

Vehicle.prototype.getType=

function

getType

()

{

return

this

.type;

};

function

Car

(name)

{

Vehicle.call(

this

,name,

'car'

);

}

Car.prototype=

Object

.create(Vehicle.prototype);

Car.prototype.constructor=Car;

Car.parent=Vehicle.prototype;

Car.prototype.getName=

function

()

{

return

'Itisacar:'

+

this

.name;

};

var

car=

new

Car(

'Tesla'

);

console

.log(car.getName());

//Itisacar:Tesla

console

.log(car.getType());

//car

AndnowlookattheES6version:

class

Vehicle{

constructor(name,type){

this

.name=name;

this

.type=type;

}

getName(){

return

this

.name;

}

getType(){

return

this

.type;

}

}

class

CarextendsVehicle{

constructor(name){

super(name,

'car'

);

}

getName(){

return

'Itisacar:'

+super.getName();

}

}

let

car=

new

Car(

'Tesla'

);

console

.log(car.getName());

//Itisacar:Tesla

console

.log(car.getType());

//car

WeseehoweasyistoimplementinheritancewithES6.It'sfinallylookinglikeinotherOOprogramminglanguages.Weuse

extendstoinheritfromanotherclassandthesuperkeywordtocalltheparentclass(function).Moreover,getName()

methodwasoverriddeninsubclassCar.

es6-guide

25

classesandinheritance

background image

super — previouslytoachievesuchfunctionalityinJavascriptrequiredtheuseofcallorapply

class

Vehicle{

constructor(name,type){

this

.name=name;

this

.type=type;

}

getName(){

return

this

.name;

}

getType(){

return

this

.type;

}

staticcreate(name,type){

return

new

Vehicle(name,type);

}

}

let

car=Vehicle.create(

'Tesla'

,

'car'

);

console

.log(car.getName());

//Tesla

console

.log(car.getType());

//car

Classesgiveusanopportunitytocreatestaticmembers.Wedon'thavetousethenewkeywordlatertoinstantiateaclass.

staticmethods(properties)arealsoinheritedandcouldbecalledbysuper

OthergreatthingsinupcomingES6aregettersandsettersforobjectproperties.Theyallowustorunthecodeonthe

readingorwritingofaproperty.

class

Car{

constructor(name){

this

._name=name;

}

setname(name){

this

._name=name;

}

getname(){

return

this

._name;

}

}

let

car=

new

Car(

'Tesla'

);

console

.log(car.name);

//Tesla

car.name=

'BMW'

;

console

.log(car.name);

//BMW

Iuse'_'prefixtocreatea(tmp)fieldtostorenameproperty.

static

get/set

es6-guide

26

classesandinheritance

background image

ThelastthingIhavetomentionispropertyshorthand,computedpropertynamesandmethodproperties.

ES6givesusshortersyntaxforcommonobjectpropertydefinition:

//ES6

let

x=

1

,

y=

2

,

obj={x,y};

console

.log(obj);

//Object{x:1,y:2}

//ES5

var

x=

1

,

y=

2

,

obj={

x:x,

y:y

};

console

.log(obj);

//Object{x:1,y:2}

Asyoucansee,thisworksbecausethepropertyvaluehasthesamenameasthepropertyidentifier.

AnotherthingisES6supportforcomputednamesinobjectpropertydefinitions:

//ES6

let

getKey=()=>

'123'

,

obj={

foo:

'bar'

,

[

'key_'

+getKey()]:

123

};

console

.log(obj);

//Object{foo:'bar',key_123:123}

//ES5

var

getKey=

function

()

{

return

'123'

;

},

obj={

foo:

'bar'

};

obj[

'key_'

+getKey()]=

123

;

console

.log(obj);

//Object{foo:'bar',key_123:123}

Theonelastthingismethodpropertiesseeninclassesabove.Wecanevenuseitinobjectdefinitions:

//ES6

let

obj={

name:

'objectname'

,

toString(){

//'function'keywordisomittedhere

return

this

.name;

}

};

console

.log(obj.toString());

//objectname

//ES5

var

obj={

name:

'objectname'

,

toString:

function

()

{

return

this

.name;

}

EnhancedObjectProperties

es6-guide

27

classesandinheritance

background image

};

console

.log(obj.toString());

//objectname

es6-guide

28

classesandinheritance

background image

Todaywehaveacoupleofwaystocreatemodules,export&importthem.JavaScriptdoesn'thaveanybuilt-inmodule

loaderyet.UpcomingECMAScript2015standardgivesusareasontomakepeoplehappy.Finally;)

Wehavethirdpartystandards:CommonJSandAMD.Themostpopular,but,unfortunately,incompatiblestandardsfor

moduleloaders.

CommonJSisknownfrom

Node.js

.It'smostlydedicatedforserversanditsupportssynchronousloading.Italso

hasacompactsyntaxfocusedonexportandrequirekeywords.

AMDandthemostpopularimplementation-

RequireJS

arededicatedforbrowsers.AMDsupportsasynchronous

loading,buthasmorecomplicatedsyntaxthanCommonJS.

ThegoalforES6is(was)tomixthesetwostandardsandmakebothusergroupshappy.

ES6givesusaneasysyntaxandsupportforasynchronousandconfigurablemoduleloading.

Asyncmodel — nocodeexecutesuntilrequestedmodulesareavailableandprocessed.

Modulescanexportmultipleobjects,whichcouldbesimplevariablesorfunctions.

export

function

multiply

(x,y)

{

return

x*y;

};

Wecanalsoexportafunctionstoredinavariable,butwehavetowrapthevariableinasetofcurlybraces.

var

multiply=

function

(x,y)

{

return

x*y;

};

export{multiply};

Wecanevenexportmanyobjectsandlikeintheaboveexample — wehavetowrapexportedstatementsinasetofcurly

bracesifweuseoneexportkeyword.

exporthello=

'HelloWorld'

;

export

function

multiply

(x,y)

{

return

x*y;

};

//===OR===

var

hello=

'HelloWorld'

,

multiply=

function

(x,y)

{

return

x*y;

};

export{hello,multiply};

Let'sjustimaginethatwehavemodules.jsfilewithallexportedstatements.Toimporttheminanotherfile(inthesame

modules

Namedexport

es6-guide

29

modules

background image

directory)weuse…import{..}from..syntax:

import{hello}from

'modules'

;

Wecanomit.jsextensionjustlikeinCommonJSandAMD.

Wecanevenimportmanystatements:

import{hello,multiply}from

'modules'

;

Importsmayalsobealiased:

import{multiplyaspow2}from

'modules'

;

..andusewildcard(*)toimportallexportedstatemets:

import*from

'modules'

;

Inourmodule,wecanhavemanynamedexports,butwecanalsohaveadefaultexport.It'sbecauseourmodulecould

bealargelibraryandwithdefaultexportwecanimportthenanentiremodule.Itcouldbealsousefulwhenourmodulehas

singlevalueormodel(class/constructor).

Onedefaultexportpermodule.

export

default

function

(x,y)

{

return

x*y;

};

Thistimewedon'thavetousecurlybracesforimportingandwehaveachancetonameimportedstatementaswewish.

importmultiplyfrom

'modules'

;

//===OR===

importpow2from

'modules'

;

//===OR===

...

Modulecanhavebothnamedexportsandadefaultexport.

//modules.js

exporthello=

'HelloWorld'

;

export

default

function

(x,y)

{

return

x*y;

};

//app.js

Defaultexport

es6-guide

30

modules

background image

importpow2,{hello}from

'modules'

;

Thedefaultexportisjustanamedexportwiththespecialnamedefault.

//modules.js

export

default

function

(x,y)

{

return

x*y;

};

//app.js

import{

default

}from

'modules'

;

Inaddition,thereisalsoaprogrammaticAPIanditallowsto:

Programmaticallyworkwithmodulesandscripts

Configuremoduleloading

SystemJS

— universaldynamicmoduleloader — loadsES6modules,AMD,CommonJSandglobalscriptsinthe

browserandNodeJS.WorkswithbothTraceurandBabel.

Moduleloadershouldsupport:

Dynamicloading

Globalnamespaceisolation

Nestedvirtualization

Compilationhooks

API

es6-guide

31

modules

background image

Promisesaren'tanewandshinyidea.IuseiteverydayinmyAngularJScode.It'sbasedon

kriskowal/q

library:

AtoolforcreatingandcomposingasynchronouspromisesinJavaScript.

It'salibraryforasynchronousprogramming,tomakeourlifeeasier.But,beforeIdescribepromises,Ihavetowrite

somethingaboutcallbacks.

UntilIremember,JavaScriptcodersusecallbacksforallbrowser-basedasynchronousfunctions(setTimeout,

XMLHttpRequest,etc.).

Lookatnaiveexample:

console

.log(

'start!'

);

setTimeout(

function

()

{

console

.log(

'ping'

);

setTimeout(

function

()

{

console

.log(

'pong'

);

setTimeout(

function

()

{

console

.log(

'end!'

);

},

1000

);

},

1000

);

},

1000

);

//start!

//after1sec:ping

//..1seclater:pong

//..and:end!

Wehavesimplecodewhichprintssomestatementstotheconsole.IusedasetTimeoutfunctionhere,toshowcallback

functionspassedtoinvokelater(1sechere).Itlooksterribleandwehaveonly3stepshere.Let'simaginemoresteps.It

willlooklikeyoubuildapyramid,notnice,readablecode.Awful,right?It'scalledcallbackhellandwehaveiteverywhere.

CallbackHell

Supportforpromisesisaveryniceadditiontothelanguage.It'sfinallynativeintheES6.

Promisesareafirstclassrepresentationofavaluethatmaybemadeavailableinthefuture.

Apromisecanbe:

fulfilled-promisesucceeded

rejected-promisefailed

pending-notfulfilledornotrejectedyet

settled-fulfilledorrejected

promises

Callbacksandcallbackhell

Promises

es6-guide

32

promises

background image

Everyreturnedpromiseobjectalsohasathenmethodtoexecutecodewhenapromiseissettled.

Yep,promiseobject,because..

callbacksarefunctions,promisesareobjects.

Callbacksareblocksofcodetoexecuteinresponseto..something(event).Promisesareobjectswhichstorean

informationaboutthestate.

Howdoesitlooklike?Let'ssee:

new

Promise((resolve,reject)=>{

//whensuccess,resolve

let

value=

'success'

;

resolve(value);

//whenanerroroccurred,reject

reject(

new

Error

(

'Somethinghappened!'

));

});

Promisecallsitsresolvefunctionwhenit'sfulfilled(success)andrejectfunctionotherwise(failure).

Promisesareobjects,soit'snotpassedasargumentslikecallbacks,it'sreturned.Thereturnstatementisanobjectwhich

isaplaceholderfortheresult,whichwillbeavailableinthefuture.

Promiseshavejustoneresponsibility-theyrepresentonlyoneevent.Callbackscanhandlemultipleevents,manytimes.

Wecanassignreturnedvalue(object)totheletstatement:

let

promise=

new

Promise((resolve,reject)=>{

//whensuccess,resolve

let

value=

'success'

;

resolve(value);

//whenanerroroccurred,reject

reject(

new

Error

(

'Somethinghappened!'

));

});

AsImentionedabove-promiseobjectalsohasathenmethodtoexecutecodewhenthepromiseissettled.

promise.then(onResolve,onReject)

WecanusethisfunctiontohandleonResolveandonRejectvaluesreturnedbyapromise.Wecanhandlesuccess,

failureorboth.

let

promise=

new

Promise((resolve,reject)=>{

//whensuccess,resolve

let

value=

'success'

;

resolve(value);

//whenanerroroccurred,reject

reject(

new

Error

(

'Somethinghappened!'

));

});

promise.then(response=>{

console

.log(response);

},error=>{

console

.log(error);

});

es6-guide

33

promises

background image

//success

Ourcodeaboveneverexecutesrejectfunction,sowecanomititforsimplicity:

let

promise=

new

Promise(resolve=>{

let

value=

'success'

;

resolve(value);

});

promise.then(response=>{

console

.log(response);

//success

});

Handlerspassedtopromise.thendon'tjusthandletheresultofthepreviouspromise-theyreturnisturnedintoanew

promise.

let

promise=

new

Promise(resolve=>{

let

value=

'success'

;

resolve(value);

});

promise.then(response=>{

console

.log(response);

//success

return

'anothersuccess'

;

}).then(response=>{

console

.log(response);

//anothersuccess

});

Youcansee,thatthecodebasedonpromisesisalwaysflat.Nomorecallbackhell.

Ifyouareonlyinterestedinrejections,youcanomitthefirstparameter.

let

promise=

new

Promise((resolve,reject)=>{

let

reason=

'failure'

;

reject(reason);

});

promise.then(

null

,

error=>{

console

.log(error);

//failure

}

);

Butisamorecompactwayofdoingthesamething-catch()method.

let

promise=

new

Promise((resolve,reject)=>{

let

reason=

'failure'

;

reject(reason);

});

promise.catch(err=>{

console

.log(err);

//failure

});

Ifwehavemorethanonethen()call,theerrorispassedonuntilthereisanerrorhandler.

let

promise=

new

Promise(resolve=>{

resolve();

});

es6-guide

34

promises

background image

promise

.then(response=>{

return

1

;

})

.then(response=>{

throw

new

Error

(

'failure'

);

})

.catch(error=>{

console

.log(error.message);

//failure

});

Wecanevencombineoneormorepromisesintonewpromiseswithouthavingtotakecareoforderingoftheunderlying

asynchronousoperationsyourself.

let

doSmth=

new

Promise(resolve=>{

resolve(

'doSmth'

);

}),

doSmthElse=

new

Promise(resolve=>{

resolve(

'doSmthElse'

);

}),

oneMore=

new

Promise(resolve=>{

resolve(

'oneMore'

);

});

Promise.all([

doSmth,

doSmthElse,

oneMore

])

.then(response=>{

let

[one,two,three]=response;

console

.log(one,two,three);

//doSmthdoSmthElseoneMore

});

Promise.all()takesanarrayofpromisesandwhenallofthemarefulfilled,itputtheirvaluesintothearray.

Therearetwomorefunctionswhichareuseful:

Promise.resolve(value)-itreturnsapromisewhichresolvestoavalueorreturnsvalueifvalueisalreadyapromise

Promise.reject(value)-returnsrejectedpromisewithvalueasvalue

Promiseshaveitspitfallaswell.Let'simagethatwhenanyexceptionisthrownwithinathenorthefunctionpassedtonew

Promise,willbesilentlydisposedofunlessmanuallyhandled.

Pitfall

es6-guide

35

promises

background image

Setsandmapswillbe(are)finallyavailableinES6!Nomorespartanwaytomanipulatedatastructures.Thischapter

explainshowwecandealwithMap,Set,WeakMapandWeakSet.

Mapsareastoreforkey/valuepairs.Keyandvaluecouldbeaprimitivesorobjectreferences.

Let'screateamap:

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

console

.log(map);

//Map{0=>'val1','1'=>'val2',Object{key:2}=>Object{key:'value'}}

Wecanalsouseaconstructortocreatethesammap,basedonarrayparampassedtotheconstructor:

let

map,

val2=

'val2'

,

val3={

key:

'value'

};

map=

new

Map([[

0

,

'val1'

],[

'1'

,val2],[{key:

2

},val3]]);

console

.log(map);

//Map{0=>'val1','1'=>'val2',Object{key:2}=>Object{key:'value'}}

Togetavaluebyusingakey,wehavetouseaget()methodtodoit(surprising):

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

console

.log(map.get(

'1'

));

//val2

Toiterateoverthemapcollection,wecanusebuilt-inforEachmethodorusenewfor..ofstructure:

//forEach

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

set,map,weak

Map

es6-guide

36

set,map,weak

background image

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

map.forEach(

function

(value,key)

{

console

.log(`Key:${key}hasvalue:${value}`);

//Key:0hasvalue:val1

//Key:1hasvalue:val2

//Key:[objectObject]hasvalue:[objectObject]

});

//for..of

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

for

(

let

entryofmap){

console

.log(`Key:${entry[

0

]}hasvalue:${entry[

1

]}`);

//Key:0hasvalue:val1

//Key:1hasvalue:val2

//Key:[objectObject]hasvalue:[objectObject]

};

Wecanalsouseacoupleofmethodstoiterate:

entries() — getallentries

keys() — getonlyallkeys

values() — getonlyallvalues

Tocheckifvalueisstoredinourmap,wecanusehas()method:

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

console

.log(map.has(

0

));

//true

console

.log(map.has(

'key'

));

//false

Todeleteentry,wehavedelete()method:

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

console

.log(map.size);

//3

map.delete(

'1'

);

es6-guide

37

set,map,weak

background image

console

.log(map.size);

//2

..andtoclearallcollection,weuseclear()method:

let

map=

new

Map(),

val2=

'val2'

,

val3={

key:

'value'

};

map.set(

0

,

'val1'

);

map.set(

'1'

,val2);

map.set({key:

2

},val3);

console

.log(map.size);

//3

map.clear();

console

.log(map.size);

//0

It'sacollectionforuniquevalues.Thevaluescouldbealsoaprimitivesorobjectreferences.

let

set=

new

Set();

set.add(

1

);

set.add(

'1'

);

set.add({key:

'value'

});

console

.log(set);

//Set{1,'1',Object{key:'value'}}

Likeamap,setallowstocreatecollectionbypassinganarraytoitsconstructor:

let

set=

new

Set([

1

,

'1'

,{key:

'value'

}]);

console

.log(set);

//Set{1,'1',Object{key:'value'}}

Toiterateoversetswehavethesametwooptions — built-inforEachfunctionorfor..ofstructure:

//forEach

let

set=

new

Set([

1

,

'1'

,{key:

'value'

}]);

set.forEach(

function

(value)

{

console

.log(value);

//1

//'1'

//Object{key:'value'}

});

//for..of

let

set=

new

Set([

1

,

'1'

,{key:

'value'

}]);

for

(

let

valueofset){

console

.log(value);

//1

//'1'

//Object{key:'value'}

};

Set

es6-guide

38

set,map,weak

background image

Setdoesn'tallowtoaddduplicates.

let

set=

new

Set([

1

,

1

,

1

,

2

,

5

,

5

,

6

,

9

]);

console

.log(set.size);

//5!

Wecanalsousehas(),delete(),clear()methods,whicharesimilartotheMapversions.

WeakMapsprovidesleak-freeobjectkeyedsidetables.It'saMapthatdoesn'tpreventitskeysfrombeinggarbage-

collected.Wedon'thavetoworryaboutmemoryleaks.

Iftheobjectisdestroyed,thegarbagecollectorremovesanentryfromtheWeakMapandfreesmemory.

Keysmustbeobjects.

IthasalmostthesameAPIlikeaMap,butwecan'titerateovertheWeakMapcollection.Wecan'tevendeterminethe

lengthofthecollectionbecausewedon'thavesizeattributehere.

TheAPIlookslikethis:

new

WeakMap([iterable])

WeakMap.prototype.get(key):any

WeakMap.prototype.set(key,value):

this

WeakMap.prototype.has(key):boolean

WeakMap.prototype.delete(key):boolean

let

wm=

new

WeakMap(),

obj={

key1:{

k:

'v1'

},

key2:{

k:

'v2'

}

};

wm.set(obj.key1,

'val1'

);

wm.set(obj.key2,

'val2'

);

console

.log(wm);

//WeakMap{Object{k:'v1'}=>'val1',Object{k:'v2'}=>'val2'}

console

.log(wm.has(obj.key1));

//true

delete

obj.key1;

console

.log(wm.has(obj.key1));

//false

LikeaWeakMap,WeakSetisaSeatthatdoesn'tpreventitsvaluesfrombeinggarbage-collected.IthassimplerAPIthan

WeakMap,becausehasonlythreemethods:

new

WeakSet([iterable])

WeakMap

WeakSet

es6-guide

39

set,map,weak

background image

WeakSet.prototype.add(value):any

WeakSet.prototype.has(value):boolean

WeakSet.prototype.delete(value):boolean

WeakSetsarecollectionsofuniqueobjectsonly.

WeakSetcollectioncan'tbeiteratedandwecannotdetermineitssize.

let

ws=

new

WeakSet(),

obj={

key1:{

k:

'v1'

},

key2:{

k:

'v2'

}

};

ws.add(obj.key1);

ws.add(obj.key2);

console

.log(ws);

//WeakSet{Object{k:'v1'},Object{k:'v2'}}

console

.log(ws.has(obj.key1));

//true

delete

obj.key1;

console

.log(ws.has(obj.key1));

//false

es6-guide

40

set,map,weak


Document Outline