table of contentsedu-9.de/uploads/books/javascript-handbook.pdf · javascript is now also the...

171

Upload: others

Post on 06-Mar-2021

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop
Page 2: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TableofContentsPreface

IntroductiontoJavaScript

ECMAScript

ES6

ES2016

ES2017

ES2018

Codingstyle

LexicalStructure

Variables

Types

Expressions

Prototypalinheritance

Classes

Exceptions

Semicolons

Quotes

TemplateLiterals

Functions

ArrowFunctions

Closures

Arrays

Loops

Events

TheEventLoop

Asynchronousprogrammingandcallbacks

Promises

AsyncandAwait

LoopsandScope

Timers

2

Page 3: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

this

StrictMode

Immediately-invokedFunctionExpressions(IIFE)

Mathoperators

TheMathobject

ESModules

CommonJS

Glossary

3

Page 4: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Preface

TheJavaScriptHandbookfollowsthe80/20rule:learnin20%ofthetimethe80%ofatopic.

Ifindthisapproachgivesawell-roundedoverview.ThisbookdoesnottrytocovereverythingunderthesunrelatedtoJavaScript.Ifyouthinksomespecifictopicshouldbeincluded,tellme.

YoucanreachmeonTwitter@flaviocopes.

Ihopethecontentsofthisbookwillhelpyouachievewhatyouwant:learnthebasicsofJavaScript.

ThisbookiswrittenbyFlavio.Ipublishwebdevelopmenttutorialseverydayonmywebsiteflaviocopes.com.

Enjoy!

Preface

4

Page 5: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

IntroductiontoJavaScriptJavaScriptisoneofthemostpopularprogramminglanguagesintheworld,andnowwidelyusedalsooutsideofthebrowser.TheriseofNode.jsinthelastfewyearsunlockedbackenddevelopment,oncethedomainofJava,Ruby,Python,PHP,andmoretraditionalserver-sidelanguages.Learnallaboutit!

IntroductionJavaScriptisoneofthemostpopularprogramminglanguagesintheworld.

Created20yearsago,it'sgoneaverylongwaysinceitshumblebeginnings.

Beingthefirst-andtheonly-scriptinglanguagethatwassupportednativelybywebbrowsers,itsimplystuck.

Inthebeginnings,itwasnotnearlypowerfulasitistoday,anditwasmainlyusedforfancyanimationsandthemarvelknownatthetimeasDHTML.

Withthegrowingneedsthatthewebplatformdemands,JavaScripthadtheresponsibilitytogrowaswell,toaccommodatetheneedsofoneofthemostwidelyusedecosystemsoftheworld.

Manythingswereintroducedintheplatform,withbrowserAPIs,butthelanguagegrewquitealotaswell.

JavaScriptisnowwidelyusedalsooutsideofthebrowser.TheriseofNode.jsinthelastfewyearsunlockedbackenddevelopment,oncethedomainofJava,Ruby,PythonandPHPandmoretraditionalserver-sidelanguages.

JavaScriptisnowalsothelanguagepoweringdatabasesandmanymoreapplications,andit'sevenpossibletodevelopembeddedapplications,mobileapps,TVsetsappsandmuchmore.Whatstartedasatinylanguageinsidethebrowserisnowthemostpopularlanguageintheworld.

AbasicdefinitionofJavaScriptJavaScriptisaprogramminglanguagethatis:

highlevel:itprovidesabstractionsthatallowyoutoignorethedetailsofthemachinewhereit'srunningon.Itmanagesmemoryautomaticallywithagarbagecollector,soyou

IntroductiontoJavaScript

5

Page 6: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

canfocusonthecodeinsteadofmanagingmemorylocations,andprovidesmanyconstructswhichallowyoutodealwithhighlypowerfulvariablesandobjects.dynamic:opposedtostaticprogramminglanguages,adynamiclanguageexecutesatruntimemanyofthethingsthatastaticlanguagedoesatcompiletime.Thishasprosandcons,anditgivesuspowerfulfeatureslikedynamictyping,latebinding,reflection,functionalprogramming,objectruntimealteration,closuresandmuchmore.dynamicallytyped:avariabledoesnotenforceatype.Youcanreassignanytypetoavariable,forexampleassigninganintegertoavariablethatholdsastring.weaklytyped:asopposedtostrongtyping,weakly(orloosely)typedlanguagesdonotenforcethetypeofanobject,allowingmoreflexibilitybutdenyingustypesafetyandtypechecking(somethingthatTypeScriptandFlowaimtoimprove)interpreted:it'scommonlyknownasaninterpretedlanguage,whichmeansthatitdoesnotneedacompilationstagebeforeaprogramcanrun,asopposedtoC,JavaorGoforexample.Inpractice,browsersdocompileJavaScriptbeforeexecutingit,forperformancereasons,butthisistransparenttoyou:thereisnoadditionalstepinvolved.multi-paradigm:thelanguagedoesnotenforceanyparticularprogrammingparadigm,unlikeJavaforexamplewhichforcestheuseofobjectorientedprogramming,orCthatforcesimperativeprogramming.YoucanwriteJavaScriptusinganobject-orientedparadigm,usingprototypesandthenew(asofES6)classessyntax.YoucanwriteJavaScriptinfunctionalprogrammingstyle,withitsfirstclassfunctions,oreveninanimperativestyle(C-like).

Incaseyou'rewondering,JavaScripthasnothingtodowithJava,it'sapoornamechoicebutwehavetolivewithit.

JavaScriptversionsLetmeintroducethetermECMAScripthere.WehaveacompleteguidededicatedtoECMAScriptwhereyoucandiveintoitmore,buttostartwith,youjustneedtoknowthatECMAScript(alsocalledES)isthenameoftheJavaScriptstandard.

JavaScriptisanimplementationofthatstandard.That'swhyyou'llhearaboutES6,ES2015,ES2016,ES2017,ES2018andsoon.

Foraverylongtime,theversionofJavaScriptthatallbrowserranwasECMAScript3.Version4wascanceledduetofeaturecreep(theyweretryingtoaddtoomanythingsatonce),whileES5wasahugeversionforJS.

ES2015,alsocalledES6,washugeaswell.

Sincethen,theonesinchargedecidedtoreleaseoneversionperyear,toavoidhavingtoomuchtimeidlebetweenreleases,andhaveafasterfeedbackloop.

IntroductiontoJavaScript

6

Page 7: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Currently,thelatestapprovedJavaScriptversionisES2017.

IntroductiontoJavaScript

7

Page 8: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ECMAScriptECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.DiscovereverythingaboutECMAScript,andthelastfeaturesaddedinES6,7,8

WheneveryoureadaboutJavaScriptyou'llinevitablyseeoneoftheseterms:

ES3ES5ES6ES7ES8ES2015ES2016ES2017ECMAScript2017ECMAScript2016

ECMAScript

8

Page 9: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ECMAScript2015

Whatdotheymean?

Theyareallreferringtoastandard,calledECMAScript.

ECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.

BesideJavaScript,otherlanguagesimplement(ed)ECMAScript,including:

ActionScript(theFlashscriptinglanguage),whichislosingpopularitysinceFlashwillbeofficiallydiscontinuedin2020JScript(theMicrosoftscriptingdialect),sinceatthetimeJavaScriptwassupportedonlybyNetscapeandthebrowserwarswereattheirpeak,MicrosofthadtobuilditsownversionforInternetExplorer

butofcourseJavaScriptisthemostpopularandwidelyusedimplementationofES.

Whythisweirdname? EcmaInternationalisaSwissstandardsassociationwhoisinchargeofdefininginternationalstandards.

WhenJavaScriptwascreated,itwaspresentedbyNetscapeandSunMicrosystemstoEcmaandtheygaveitthenameECMA-262aliasECMAScript.

ThispressreleasebyNetscapeandSunMicrosystems(themakerofJava)mighthelpfigureoutthenamechoice,whichmightincludelegalandbrandingissuesbyMicrosoftwhichwasinthecommittee,accordingtoWikipedia.

AfterIE9,MicrosoftstoppedstoppedbrandingitsESsupportinbrowsersasJScriptandstartedcallingitJavaScript(atleast,Icouldnotfindreferencestoitanymore)

Soasof201x,theonlypopularlanguagesupportingtheECMAScriptspecisJavaScript.

CurrentECMAScriptversionThecurrentECMAScriptversionisES2018.

ItwasreleasedinJune2018.

Whenisthenextversioncomingout?HistoricallyJavaScripteditionshavebeenstandardizedduringthesummer,sowecanexpectECMAScript2019tobereleasedinsummer2019,butthisisjustspeculation.

ECMAScript

9

Page 10: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

WhatisTC39TC39isthecommitteethatevolvesJavaScript.

ThemembersofTC39arecompaniesinvolvedinJavaScriptandbrowservendors,includingMozilla,Google,Facebook,Apple,Microsoft,Intel,PayPal,SalesForceandothers.

Everystandardversionproposalmustgothroughvariousstages,whichareexplainedhere.

ESVersionsIfounditpuzzlingwhysometimesanESversionisreferencedbyeditionnumberandsometimesbyyear,andIamconfusedbytheyearbychancebeing-1onthenumber,whichaddstothegeneralconfusionaroundJS/ES

BeforeES2015,ECMAScriptspecificationswerecommonlycalledbytheiredition.SoES5istheofficialnamefortheECMAScriptspecificationupdatepublishedin2009.

Whydoesthishappen?DuringtheprocessthatledtoES2015,thenamewaschangedfromES6toES2015,butsincethiswasdonelate,peoplestillreferenceditasES6,andthecommunityhasnotlefttheeditionnamingbehind-theworldisstillcallingESreleasesbyeditionnumber.

Thistableshouldclearthingsabit:

Edition Officialname Datepublished

ES9 ES2018 June2018

ES8 ES2017 June2017

ES7 ES2016 June2016

ES6 ES2015 June2015

ES5.1 ES5.1 June2011

ES5 ES5 December2009

ES4 ES4 Abandoned

ES3 ES3 December1999

ES2 ES2 June1998

ES1 ES1 June1997

ESNext

ECMAScript

10

Page 11: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES.NextisanamethatalwaysindicatesthenextversionofJavaScript.

Soatthetimeofwriting,ES9hasbeenreleased,andES.NextisES10

ECMAScript

11

Page 12: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES6ECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.DiscovereverythingaboutECMAScript,andthelastfeaturesaddedinES6,akaES2015

ECMAScript2015,alsoknownasES6,isafundamentalversionoftheECMAScriptstandard.

Published4yearsafterthelateststandardrevision,ECMAScript5.1,italsomarkedtheswitchfromeditionnumbertoyearnumber.

SoitshouldnotbenamedasES6(althougheveryonecallsitassuch)butES2015instead.

ES5was10yearsinthemaking,from1999to2009,andassuchitwasalsoafundamentalandveryimportantrevisionofthelanguage,butnowmuchtimehaspassedthatit'snotworthdiscussinghowpre-ES5codeworked.

SincethislongtimepassedbetweenES5.1andES6,thereleaseisfullofimportantnewfeaturesandmajorchangesinsuggestedbestpracticesindevelopingJavaScriptprograms.TounderstandhowfundamentalES2015is,justkeepinmindthatwiththisversion,thespecificationdocumentwentfrom250pagesto~600.

ThemostimportantchangesinES2015include

ArrowfunctionsPromisesGeneratorsletand constClassesModulesMultilinestringsTemplateliteralsDefaultparametersThespreadoperator|DestructuringassignmentsEnhancedobjectliteralsThefor..ofloopMapandSet

Eachofthemhasadedicatedsectioninthisarticle.

ArrowFunctions

ES6

12

Page 13: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ArrowfunctionssincetheirintroductionchangedhowmostJavaScriptcodelooks(andworks).

Visually,it'sasimpleandwelcomechange,from:

constfoo=functionfoo(){

//...

}

to

constfoo=()=>{

//...

}

Andifthefunctionbodyisaone-liner,just:

constfoo=()=>doSomething()

Also,ifyouhaveasingleparameter,youcouldwrite:

constfoo=param=>doSomething(param)

Thisisnotabreakingchange,regular functionswillcontinuetoworkjustasbefore.

Anew thisscopeThe thisscopewitharrowfunctionsisinheritedfromthecontext.

Withregular functions thisalwaysreferstothenearestfunction,whilewitharrowfunctionsthisproblemisremoved,andyouwon'tneedtowrite varthat=thiseveragain.

PromisesPromises(checkthefullguidetopromises)allowustoeliminatethefamous"callbackhell",althoughtheyintroduceabitmorecomplexity(whichhasbeensolvedinES2017with async,ahigherlevelconstruct).

PromiseshavebeenusedbyJavaScriptdeveloperswellbeforeES2015,withmanydifferentlibrariesimplementations(e.g.jQuery,q,deferred.js,vow...),andthestandardputacommongroundacrossdifferences.

Byusingpromisesyoucanrewritethiscode

ES6

13

Page 14: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

setTimeout(function(){

console.log('Ipromisedtorunafter1s')

setTimeout(function(){

console.log('Ipromisedtorunafter2s')

},1000)

},1000)

as

constwait=()=>newPromise((resolve,reject)=>{

setTimeout(resolve,1000)

})

wait().then(()=>{

console.log('Ipromisedtorunafter1s')

returnwait()

})

.then(()=>console.log('Ipromisedtorunafter2s'))

GeneratorsGeneratorsareaspecialkindoffunctionwiththeabilitytopauseitself,andresumelater,allowingothercodetoruninthemeantime.

Thecodedecidesthatithastowait,soitletsothercode"inthequeue"torun,andkeepstherighttoresumeitsoperations"whenthethingit'swaitingfor"isdone.

Allthisisdonewithasingle,simplekeyword: yield.Whenageneratorcontainsthatkeyword,theexecutionishalted.

Ageneratorcancontainmany yieldkeywords,thushaltingitselfmultipletimes,andit'sidentifiedbythe *functionkeyword,whichisnottobeconfusedwiththepointerdereferenceoperatorusedinlowerlevelprogramminglanguagessuchasC,C++orGo.

GeneratorsenablewholenewparadigmsofprogramminginJavaScript,allowing:

2-waycommunicationwhileageneratorisrunninglong-livedwhileloopswhichdonotfreezeyourprogram

Hereisanexampleofageneratorwhichexplainshowitallworks.

function*calculator(input){

vardoubleThat=2*(yield(input/2))

varanother=yield(doubleThat)

return(input*doubleThat*another)

}

ES6

14

Page 15: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Weinitializeitwith

constcalc=calculator(10)

Thenwestarttheiteratoronourgenerator:

calc.next()

Thisfirstiterationstartstheiterator.Thecodereturnsthisobject:

{

done:false

value:5

}

Whathappensis:thecoderunsthefunction,with input=10asitwaspassedinthegeneratorconstructor.Itrunsuntilitreachesthe yield,andreturnsthecontentof yield:input/2=5.Sowegotavalueof5,andtheindicationthattheiterationisnotdone(thefunctionisjustpaused).

Intheseconditerationwepassthevalue 7:

calc.next(7)

andwhatwegotbackis:

{

done:false

value:14

}

7wasplacedasthevalueof doubleThat.Important:youmightreadlike input/2wastheargument,butthat'sjustthereturnvalueofthefirstiteration.Wenowskipthat,andusethenewinputvalue, 7,andmultiplyitby2.

Wethenreachthesecondyield,andthatreturns doubleThat,sothereturnedvalueis 14.

Inthenext,andlast,iteration,wepassin100

calc.next(100)

andinreturnwegot

ES6

15

Page 16: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

{

done:true

value:14000

}

Astheiterationisdone(nomoreyieldkeywordsfound)andwejustreturn (input*doubleThat*another)whichamountsto 10*14*100.

letand constvaristraditionallyfunctionscoped.

letisanewvariabledeclarationwhichisblockscoped.

Thismeansthatdeclaring letvariablesinaforloop,insideaniforinaplainblockisnotgoingtoletthatvariable"escape"theblock,while varsarehoisteduptothefunctiondefinition.

constisjustlike let,butimmutable.

InJavaScriptmovingforward,you'llseelittletono vardeclarationsanymore,just letandconst.

constinparticular,maybesurprisingly,isverywidelyusednowadayswithimmutabilitybeingverypopular.

ClassesTraditionallyJavaScriptistheonlymainstreamlanguagewithprototype-basedinheritance.ProgrammersswitchingtoJSfromclass-basedlanguagefounditpuzzling,butES2015introducedclasses,whicharejustsyntacticsugarovertheinnerworking,butchangedalothowwebuildJavaScriptprograms.

Nowinheritanceisveryeasyandresemblesotherobject-orientedprogramminglanguages:

classPerson{

constructor(name){

this.name=name

}

hello(){

return'Hello,Iam'+this.name+'.'

}

}

ES6

16

Page 17: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

classActorextendsPerson{

hello(){

returnsuper.hello()+'Iamanactor.'

}

}

vartomCruise=newActor('TomCruise')

tomCruise.hello()

(theaboveprogramprints"Hello,IamTomCruise.Iamanactor.")

Classesdonothaveexplicitclassvariabledeclarations,butyoumustinitializeanyvariableintheconstructor.

Constructor

Classeshaveaspecialmethodcalled constructorwhichiscalledwhenaclassisinitializedvia new.

Super

Theparentclasscanbereferencedusing super().

Gettersandsetters

Agetterforapropertycanbedeclaredas

classPerson{

getfullName(){

return`${this.firstName}${this.lastName}`

}

}

Settersarewritteninthesameway:

classPerson{

setage(years){

this.theAge=years

}

}

Modules

ES6

17

Page 18: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

BeforeES2015,therewereatleast3majormodulescompetingstandards,whichfragmentedthecommunity:

AMDRequireJSCommonJS

ES2015standardizedtheseintoacommonformat.

Importingmodules

Importingisdoneviathe import...from...construct:

import*from'mymodule'

importReactfrom'react'

import{React,Component}from'react'

importReactasMyLibraryfrom'react'

Exportingmodules

Youcanwritemodulesandexportanythingtoothermodulesusingthe exportkeyword:

exportvarfoo=2

exportfunctionbar(){/*...*/}

TemplateLiteralsTemplateliteralsareanewsyntaxtocreatestrings:

constaString=`Astring`

Theyprovideawaytoembedexpressionsintostrings,effectivelyinterpolatingthevalues,byusingthe ${a_variable}syntax:

constvar='test'

conststring=`something${var}`//somethingtest

Youcanperformmorecomplexexpressionsaswell:

conststring=`something${1+2+3}`

conststring2=`something${foo()?'x':'y'}`

ES6

18

Page 19: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

andstringscanspanovermultiplelines:

conststring3=`Hey

this

string

isawesome!`

Comparehowweusedtodomultilinestringspre-ES2015:

varstr='One\n'+

'Two\n'+

'Three'

Seethispostforanin-depthguideontemplateliterals

DefaultparametersFunctionsnowsupportdefaultparameters:

constfoo=function(index=0,testing=true){/*...*/}

foo()

ThespreadoperatorYoucanexpandanarray,anobjectorastringusingthespreadoperator ....

Let'sstartwithanarrayexample.Given

consta=[1,2,3]

youcancreateanewarrayusing

constb=[...a,4,5,6]

Youcanalsocreateacopyofanarrayusing

constc=[...a]

Thisworksforobjectsaswell.Cloneanobjectwith:

ES6

19

Page 20: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

constnewObj={...oldObj}

Usingstrings,thespreadoperatorcreatesanarraywitheachcharinthestring:

consthey='hey'

constarrayized=[...hey]//['h','e','y']

Thisoperatorhassomeprettyusefulapplications.Themostimportantoneistheabilitytouseanarrayasfunctionargumentinaverysimpleway:

constf=(foo,bar)=>{}

consta=[1,2]

f(...a)

(inthepastyoucoulddothisusing f.apply(null,a)butthat'snotasniceandreadable)

DestructuringassignmentsGivenanobject,youcanextractjustsomevaluesandputthemintonamedvariables:

constperson={

firstName:'Tom',

lastName:'Cruise',

actor:true,

age:54,//madeup

}

const{firstName:name,age}=person

nameand agecontainthedesiredvalues.

Thesyntaxalsoworksonarrays:

consta=[1,2,3,4,5]

[first,second,,,fifth]=a

EnhancedObjectLiteralsInES2015ObjectLiteralsgainedsuperpowers.

Simplersyntaxtoincludevariables

ES6

20

Page 21: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Insteadofdoing

constsomething='y'

constx={

something:something

}

youcando

constsomething='y'

constx={

something

}

Prototype

Aprototypecanbespecifiedwith

constanObject={y:'y'}

constx={

__proto__:anObject

}

super()

constanObject={y:'y',test:()=>'zoo'}

constx={

__proto__:anObject,

test(){

returnsuper.test()+'x'

}

}

x.test()//zoox

Dynamicproperties

constx={

['a'+'_'+'b']:'z'

}

x.a_b//z

For-ofloop

ES6

21

Page 22: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES5backin2009introduced forEach()loops.Whilenice,theyofferednowaytobreak,likeforloopsalwaysdid.

ES2015introducedthe for-ofloop,whichcombinestheconcisenessof forEachwiththeabilitytobreak:

//iterateoverthevalue

for(constvof['a','b','c']){

console.log(v);

}

//gettheindexaswell,using`entries()`

for(const[i,v]of['a','b','c'].entries()){

console.log(i,v);

}

MapandSetMapandSet(andtheirrespectivegarbagecollectedWeakMapandWeakSet)aretheofficialimplementationsoftwoverypopulardatastructures.

ES6

22

Page 23: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES2016ECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.DiscovereverythingaboutECMAScript,andthelastfeaturesaddedinES2016,akaES7

ES7,officiallyknownasECMAScript2016,wasfinalizedinJune2016.

ComparedtoES6,ES7isatinyreleaseforJavaScript,containingjusttwofeatures:

Array.prototype.includesExponentiationOperator

Array.prototype.includes()Thisfeatureintroducesamorereadablesyntaxforcheckingifanarraycontainsanelement.

WithES6andlower,tocheckifanarraycontainedanelementyouhadtouse indexOf,whichcheckstheindexinthearray,andreturns -1iftheelementisnotthere.

Since -1isevaluatedasatruevalue,youcouldnotdoforexample

if(![1,2].indexOf(3)){

console.log('Notfound')

}

WiththisfeatureintroducedinES7wecando

if(![1,2].includes(3)){

console.log('Notfound')

}

ExponentiationOperatorTheexponentiationoperator **istheequivalentof Math.pow(),butbroughtintothelanguageinsteadofbeingalibraryfunction.

Math.pow(4,2)==4**2

ThisfeatureisaniceadditionformathintensiveJSapplications.

ES2016

23

Page 24: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

The **operatorisstandardizedacrossmanylanguagesincludingPython,Ruby,MATLAB,Lua,Perlandmanyothers.

ES2016

24

Page 25: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES2017ECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.DiscovereverythingaboutECMAScript,andthelastfeaturesaddedinES2017,akaES8

ECMAScript2017,edition8oftheECMA-262Standard(alsocommonlycalledES2017orES8),wasfinalizedinJune2017.

ComparedtoES6,ES8isatinyreleaseforJavaScript,butstillitintroducesveryusefulfeatures:

StringpaddingObject.valuesObject.entriesObject.getOwnPropertyDescriptors()TrailingcommasinfunctionparameterlistsandcallsAsyncfunctionsSharedmemoryandatomics

StringpaddingThepurposeofstringpaddingistoaddcharacterstoastring,soitreachesaspecificlength.

ES2017introducestwo Stringmethods: padStart()and padEnd().

padStart(targetLength[,padString])

padEnd(targetLength[,padString])

Sampleusage:

padStart()

'test'.padStart(4) 'test'

'test'.padStart(5) '_test'

'test'.padStart(8) '____test'

'test'.padStart(8,'abcd') 'abcdtest'

padEnd()

'test'.padEnd(4) 'test'

ES2017

25

Page 26: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

'test'.padEnd(5) 'test_'

'test'.padEnd(8) 'test____'

'test'.padEnd(8,'abcd') 'testabcd'

(inthetable,_=space)

Object.values()Thismethodreturnsanarraycontainingalltheobjectownpropertyvalues.

Usage:

constperson={name:'Fred',age:87}

Object.values(person)//['Fred',87]

Object.values()alsoworkswitharrays:

constpeople=['Fred','Tony']

Object.values(people)//['Fred','Tony']

Object.entries()Thismethodreturnsanarraycontainingalltheobjectownproperties,asanarrayof [key,value]pairs.

Usage:

constperson={name:'Fred',age:87}

Object.entries(person)//[['name','Fred'],['age',87]]

Object.entries()alsoworkswitharrays:

constpeople=['Fred','Tony']

Object.entries(people)//[['0','Fred'],['1','Tony']]

getOwnPropertyDescriptors()Thismethodreturnsallown(non-inherited)propertiesdescriptorsofanobject.

AnyobjectinJavaScripthasasetofproperties,andeachofthesepropertieshasadescriptor.

ES2017

26

Page 27: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Adescriptorisasetofattributesofaproperty,andit'scomposedbyasubsetofthefollowing:

value:thevalueofthepropertywritable:truethepropertycanbechangedget:agetterfunctionfortheproperty,calledwhenthepropertyisreadset:asetterfunctionfortheproperty,calledwhenthepropertyissettoavalueconfigurable:iffalse,thepropertycannotberemovednoranyattributecanbechanged,exceptitsvalueenumerable:trueifthepropertyisenumerable

Object.getOwnPropertyDescriptors(obj)acceptsanobject,andreturnsanobjectwiththesetofdescriptors.

Inwhatwayisthisuseful?

ES2015gaveus Object.assign(),whichcopiesallenumerableownpropertiesfromoneormoreobjects,andreturnanewobject.

Howeverthereisaproblemwiththat,becauseitdoesnotcorrectlycopiespropertieswithnon-defaultattributes.

Ifanobjectforexamplehasjustasetter,it'snotcorrectlycopiedtoanewobject,usingObject.assign().

Forexamplewith

constperson1={

setname(newName){

console.log(newName)

}

}

Thiswon'twork:

constperson2={}

Object.assign(person2,person1)

Butthiswillwork:

constperson3={}

Object.defineProperties(person3,Object.getOwnPropertyDescriptors(person1))

Asyoucanseewithasimpleconsoletest:

person1.name='x'

ES2017

27

Page 28: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

;('x')

person2.name='x'

person3.name='x'

;('x')

person2missesthesetter,itwasnotcopiedover.

ThesamelimitationgoesforshallowcloningobjectswithObject.create().

TrailingcommasThisfeatureallowstohavetrailingcommasinfunctiondeclarations,andinfunctionscalls:

constdoSomething=(var1,var2)=>{

//...

}

doSomething('test2','test2')

Thischangewillencouragedeveloperstostoptheugly"commaatthestartoftheline"habit.

AsyncfunctionsCheckthededicatedpostaboutasync/await

ES2017introducedtheconceptofasyncfunctions,andit'sthemostimportantchangeintroducedinthisECMAScriptedition.

Asyncfunctionsareacombinationofpromisesandgeneratorstoreducetheboilerplatearoundpromises,andthe"don'tbreakthechain"limitationofchainingpromises.

Whytheyareuseful

It'sahigherlevelabstractionoverpromises.

WhenPromiseswereintroducedinES2015,theyweremeanttosolveaproblemwithasynchronouscode,andtheydid,butoverthe2yearsthatseparatedES2015andES2017,itwasclearthatpromisescouldnotbethefinalsolution.Promiseswereintroducedtosolvethefamouscallbackhellproblem,buttheyintroducedcomplexityontheirown,andsyntaxcomplexity.Theyweregoodprimitivesaroundwhichabettersyntaxcouldbeexposedtothedevelopers:enterasyncfunctions.

ES2017

28

Page 29: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Aquickexample

Codemakinguseofasynchronousfunctionscanbewrittenas

functiondoSomethingAsync(){

returnnewPromise(resolve=>{

setTimeout(()=>resolve('Ididsomething'),3000)

})

}

asyncfunctiondoSomething(){

console.log(awaitdoSomethingAsync())

}

console.log('Before')

doSomething()

console.log('After')

Theabovecodewillprintthefollowingtothebrowserconsole:

Before

After

Ididsomething//after3s

Multipleasyncfunctionsinseries

Asyncfunctionscanbechainedveryeasily,andthesyntaxismuchmorereadablethanwithplainpromises:

functionpromiseToDoSomething(){

returnnewPromise(resolve=>{

setTimeout(()=>resolve('Ididsomething'),10000)

})

}

asyncfunctionwatchOverSomeoneDoingSomething(){

constsomething=awaitpromiseToDoSomething()

returnsomething+'andIwatched'

}

asyncfunctionwatchOverSomeoneWatchingSomeoneDoingSomething(){

constsomething=awaitwatchOverSomeoneDoingSomething()

returnsomething+'andIwatchedaswell'

}

watchOverSomeoneWatchingSomeoneDoingSomething().then(res=>{

console.log(res)

})

ES2017

29

Page 30: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

SharedMemoryandAtomicsWebWorkersareusedtocreatemultithreadedprogramsinthebrowser.

Theyofferamessagingprotocolviaevents.SinceES2017,youcancreateasharedmemoryarraybetweenwebworkersandtheircreator,usinga SharedArrayBuffer.

Sinceit'sunknownhowmuchtimewritingtoasharedmemoryportiontakestopropagate,Atomicsareawaytoenforcethatwhenreadingavalue,anykindofwritingoperationiscompleted.

Anymoredetailonthiscanbefoundinthespecproposal,whichhassincebeenimplemented.

ES2017

30

Page 31: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES2018ECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.DiscovereverythingaboutECMAScript,andthelastfeaturesaddedinES2018,akaES9

ES2018isthelatestversionoftheECMAScriptstandard.

Whatarethenewthingsintroducedinit?

Rest/SpreadPropertiesES6introducedtheconceptofarestelementwhenworkingwitharraydestructuring:

constnumbers=[1,2,3,4,5]

[first,second,...others]=numbers

andspreadelements:

constnumbers=[1,2,3,4,5]

constsum=(a,b,c,d,e)=>a+b+c+d+e

constsum=sum(...numbers)

ES2018introducesthesamebutforobjects.

Restproperties:

const{first,second,...others}={first:1,second:2,third:3,fourth:4,fifth:5

}

first//1

second//2

others//{third:3,fourth:4,fifth:5}

Spreadpropertiesallowtocreateanewobjectbycombiningthepropertiesoftheobjectpassedafterthespreadoperator:

constitems={first,second,...others}

items//{first:1,second:2,third:3,fourth:4,fifth:5}

Asynchronousiteration

ES2018

31

Page 32: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thenewconstruct for-await-ofallowsyoutouseanasynciterableobjectastheloopiteration:

forawait(constlineofreadLines(filePath)){

console.log(line)

}

Sincethisuses await,youcanuseitonlyinside asyncfunctions,likeanormal await(seeasync/await)

Promise.prototype.finally()Whenapromiseisfulfilled,successfullyitcallsthe then()methods,oneafteranother.

Ifsomethingfailsduringthis,the then()methodsarejumpedandthe catch()methodisexecuted.

finally()allowyoutorunsomecoderegardlessofthesuccessfulornotsuccessfulexecutionofthepromise:

fetch('file.json')

.then(data=>data.json())

.catch(error=>console.error(error))

.finally(()=>console.log('finished'))

RegularExpressionimprovements

RegExplookbehindassertions:matchastringdependingonwhatprecedesit

Thisisalookahead:youuse ?=tomatchastringthat'sfollowedbyaspecificsubstring:

/Roger(?=Waters)/

/Roger(?=Waters)/.test('Rogerismydog')//false

/Roger(?=Waters)/.test('RogerismydogandRogerWatersisafamousmusician')//true

?!performstheinverseoperation,matchingifastringisnotfollowedbyaspecificsubstring:

/Roger(?!Waters)/

/Roger(?!Waters)/.test('Rogerismydog')//true

/Roger(?!Waters)/.test('RogerWatersisafamousmusician')//false

ES2018

32

Page 33: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Lookaheadsusethe ?=symbol.Theywerealreadyavailable.

Lookbehinds,anewfeature,uses ?<=.

/(?<=Roger)Waters/

/(?<=Roger)Waters/.test('PinkWatersismydog')//false

/(?<=Roger)Waters/.test('RogerismydogandRogerWatersisafamousmusician')//true

Alookbehindisnegatedusing ?<!:

/(?<!Roger)Waters/

/(?<!Roger)Waters/.test('PinkWatersismydog')//true

/(?<!Roger)Waters/.test('RogerismydogandRogerWatersisafamousmusician')//false

Unicodepropertyescapes \p{…}and \P{…}

Inaregularexpressionpatternyoucanuse \dtomatchanydigit, \stomatchanycharacterthat'snotawhitespace, \wtomatchanyalphanumericcharacter,andsoon.

ThisnewfeatureextendsthisconcepttoallUnicodecharactersintroducing \p{}andisnegation \P{}.

Anyunicodecharacterhasasetofproperties.Forexample Scriptdeterminesthelanguagefamily, ASCIIisabooleanthat'strueforASCIIcharacters,andsoon.Youcanputthispropertyinthegraphparentheses,andtheregexwillcheckforthattobetrue:

/^\p{ASCII}+$/u.test('abc')//✅

/^\p{ASCII}+$/u.test('ABC@')//✅

/^\p{ASCII}+$/u.test('ABC ')//❌

ASCII_Hex_Digitisanotherbooleanproperty,thatchecksifthestringonlycontainsvalidhexadecimaldigits:

/^\p{ASCII_Hex_Digit}+$/u.test('0123456789ABCDEF')//✅

/^\p{ASCII_Hex_Digit}+$/u.test('h')//❌

Therearemanyotherbooleanproperties,whichyoujustcheckbyaddingtheirnameinthegraphparentheses,including Uppercase, Lowercase, White_Space, Alphabetic, Emojiandmore:

/^\p{Lowercase}$/u.test('h')//✅

/^\p{Uppercase}$/u.test('H')//✅

ES2018

33

Page 34: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

/^\p{Emoji}+$/u.test('H')//❌

/^\p{Emoji}+$/u.test(' ')//✅

Inadditiontothosebinaryproperties,youcancheckanyoftheunicodecharacterpropertiestomatchaspecificvalue.Inthisexample,Icheckifthestringiswritteninthegreekorlatinalphabet:

/^\p{Script=Greek}+$/u.test('ελληνικά')//✅

/^\p{Script=Latin}+$/u.test('hey')//✅

Readmoreaboutallthepropertiesyoucanusedirectlyontheproposal.

Namedcapturinggroups

InES2018acapturinggroupcanbeassignedtoaname,ratherthanjustbeingassignedaslotintheresultarray:

constre=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/

constresult=re.exec('2015-01-02')

//result.groups.year==='2015';

//result.groups.month==='01';

//result.groups.day==='02';

The sflagforregularexpressions

The sflag,shortforsingleline,causesthe .tomatchnewlinecharactersaswell.Withoutit,thedotmatchesregularcharactersbutnotthenewline:

/hi.welcome/.test('hi\nwelcome')//false

/hi.welcome/s.test('hi\nwelcome')//true

ES2018

34

Page 35: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

CodingstyleThisJavaScriptCodingStyleisthesetofconventionsIuseeverydaywhenusingJavaScript.It'salivedocument,withthemainsetofrulesIfollow

Acodingstyleisanagreementwithyourselfandyourteam,tokeepconsistencyonaproject.

Anifyoudon'thaveateam,it'sanagreementwithyou,toalwayskeepyourcodeuptoyourstandards.

Havingfixedrulesonyourcodewritingformathelpsalotinordertohaveamorereadableandmanagedcode.

PopularStyleGuidesThereareaquiteafewofthemaround,herearethe2mostcommononesintheJavaScriptworld:

TheGoogleJavaScriptStyleGuideTheAirBnbJavaScriptStyleGuide

It'suptoyoutofollowoneofthose,orcreateyourownstyleguide.

BeconsistentwiththeprojectyouworkonEvenifyoupreferasetofstyles,whenworkingonaprojectyoushouldusethatprojectstyle.

AnOpenSourceprojectonGitHubmightfollowasetofrules,anotherprojectyouworkonwithateammightfollowanentirelydifferentone.

Prettierisanawesometoolthatenforcescodeformatting,useit.

MyownpreferencesMyowntakeonJavaScriptstyleis:

AlwaysusethelatestESversion.UseBabelifoldbrowsersupportisnecessary.

Indentation:usespacesinsteadoftabs,indentusing2spaces.

Semicolons:don'tusesemicolons.

Codingstyle

35

Page 36: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Linelength:trytocutlinesat80chars,ifpossible.

InlineComments:useinlinecommentsinyourcode.Useblockcommentsonlytodocument.

Nodeadcode:Don'tleaveoldcodecommented,"justincase"itwillbeusefullater.Keeponlythecodeyouneednow,versioncontrol/yournotesappismeantforthis.

Onlycommentwhenuseful:Don'taddcommentsthatdon'thelpunderstandwhatthecodeisdoing.Ifthecodeisself-explainingthroughtheuseofgoodvariableandfunctionnaming,andJSDocfunctioncomments,don'taddacomment.

Variabledeclarations:alwaysdeclarevariablestoavoidpollutingtheglobalobject.Neveruse var.Defaultto const,onlyuse letifyoureassignthevariable.

Constants:declareallconstantsinCAPS.Use _toseparatewordsina VARIABLE_NAME.

Functions:usearrowfunctionsunlessyouhaveaspecificreasontouseregularfunctions,likeinobjectmethodsorconstructors,duetohow thisworks.Declarethemasconst,anduseimplicitreturnsifpossible.

consttest=(a,b)=>a+b

constanother=a=>a+2

Feelfreetousenestedfunctionstohidehelperfunctionstotherestofthecode.

Names:functionnames,variablenamesandmethodnamesalwaysstartwithalowercaseletter(unlessyouidentifythemasprivate,readbelow),andarecamelCased.Onlyconstructorfunctionsandclassnamesshouldstartcapitalized.Ifyouuseaframeworkthatrequiresspecificconventions,changeyourhabitsaccordingly.Filenamesshouldallbelowercase,withwordsseparatedby -.

Statement-specificformatsandrules:

if

if(condition){

statements

}

if(condition){

statements

}else{

statements

}

if(condition){

statements

}elseif(condition){

Codingstyle

36

Page 37: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

statements

}else{

statements

}

for

Alwaysinitializethelengthintheinitializationtocacheit,don'tinsertitinthecondition.

Avoidusing forinexceptwithusedinconjunctionwith .hasOwnProperty().Prefer forof(seeJavaScriptLoops)

for(initialization;condition;update){

statements

}

while

while(condition){

statements

}

do

do{

statements

}while(condition);

switch

switch(expression){

caseexpression:

statements

default:

statements

}

try

try{

statements

}catch(variable){

statements

}

try{

statements

}catch(variable){

Codingstyle

37

Page 38: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

statements

}finally{

statements

}

Whitespace:usewhitespacewiselytoimprovereadability:putawhitespaceafterakeywordfollowedbya (;before&afterabinaryoperation( +, -, /, *, &&..);insidetheforstatement,aftereach ;toseparateeachpartofthestatement;aftereach ,.

Newlines:usenewlinestoseparateblocksofcodethatperformlogicallyrelatedoperations.

Quotesfavorsinglequotes 'insteadofdoublequotes ".DoublequotesareastandardinHTMLattributes,sousingsinglequoteshelpsremoveproblemswhendealingwithHTMLstrings.Usetemplateliteralswhenappropriateinsteadofvariableinterpolation.

Codingstyle

38

Page 39: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

LexicalStructureAdeepdiveintothebuildingblocksofJavaScript:unicode,semicolons,whitespace,casesensitivity,comments,literals,identifiersandreservedwords

UnicodeJavaScriptiswritteninUnicode.ThismeansyoucanuseEmojisasvariablenames,butmoreimportantly,youcanwriteidentifiersinanylanguage,forexampleJapaneseorChinese,withsomerules.

SemicolonsJavaScripthasaveryC-likesyntax,andyoumightseelotsofcodesamplesthatfeaturesemicolonsattheendofeachline.

Semicolonsaren'tmandatory,andJavaScriptdoesnothaveanyproblemincodethatdoesnotusethem,andlatelymanydevelopers,especiallythosecomingfromlanguagesthatdonothavesemicolons,startedavoidingusingthem.

Youjustneedtoavoiddoingstrangethingsliketypingstatementsonmultiplelines

return

variable

orstartingalinewithparentheses( [or ()andyou'llbesafe99.9%ofthetimes(andyourlinterwillwarnyou).

Itgoestopersonalpreference,andlatelyIhavedecidedtoneveradduselesssemicolons,soonthissiteyou'llneverseethem.

WhitespaceJavaScriptdoesnotconsiderwhitespacemeaningful.Spacesandlinebreakscanbeaddedinanyfashionyoumightlike,eventhoughthisisintheory.

Inpractice,youwillmostlikelykeepawelldefinedstyleandadheretowhatpeoplecommonlyuse,andenforcethisusingalinterorastyletoolsuchasPrettier.

LexicalStructure

39

Page 40: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ForexampleIliketoalways2characterstoindent.

CasesensitiveJavaScriptiscasesensitive.Avariablenamed somethingisdifferentfrom Something.

Thesamegoesforanyidentifier.

CommentsYoucanusetwokindofcommentsinJavaScript:

/**/

//

Thefirstcanspanovermultiplelinesandneedstobeclosed.

Thesecondcommentseverythingthat'sonitsright,onthecurrentline.

LiteralsandIdentifiersWedefineasliteralavaluethatiswritteninthesourcecode,forexampleanumber,astring,abooleanoralsomoreadvancedconstructs,likeObjectLiteralsorArrayLiterals:

5

'Test'

true

['a','b']

{color:'red',shape:'Rectangle'}

Anidentifierisasequenceofcharactersthatcanbeusedtoidentifyavariable,afunction,anobject.Itcanstartwithaletter,thedollarsign $oranunderscore _,anditcancontaindigits.UsingUnicode,alettercanbeanyallowedchar,forexampleanemoji .

Test

test

TEST

_test

Test1

$test

LexicalStructure

40

Page 41: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ThedollarsigniscommonlyusedtoreferenceDOMelements.

ReservedwordsYoucan'tuseasidentifiersanyofthefollowingwords:

break

do

instanceof

typeof

case

else

new

var

catch

finally

return

void

continue

for

switch

while

debugger

function

this

with

default

if

throw

delete

in

try

class

enum

extends

super

const

export

import

implements

let

private

public

interface

package

protected

static

yield

becausetheyarereservedbythelanguage.

LexicalStructure

41

Page 42: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

LexicalStructure

42

Page 43: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

VariablesAvariableisaliteralassignedtoanidentifier,soyoucanreferenceanduseitlaterintheprogram.LearnhowtodeclareonewithJavaScript

IntroductiontoJavaScriptVariablesAvariableisaliteralassignedtoanidentifier,soyoucanreferenceanduseitlaterintheprogram.

VariablesinJavaScriptdonothaveanytypeattached.Onceyouassignaspecificliteraltypetoavariable,youcanlaterreassignthevariabletohostanyothertype,withouttypeerrorsoranyissue.

ThisiswhyJavaScriptissometimesreferencedas"untyped".

Avariablemustbedeclaredbeforeyoucanuseit.Thereare3waystodoit,using var, letor const,andthose3waysdifferinhowyoucaninteractwiththevariablelateron.

Using varUntilES2015, varwastheonlyconstructavailablefordefiningvariables.

vara=0

Ifyouforgettoadd varyouwillbeassigningavaluetoanundeclaredvariable,andtheresultsmightvary.

Inmodernenvironments,withstrictmodeenabled,youwillgetanerror.Inolderenvironments(orwithstrictmodedisabled)thiswillsimplyinitializethevariableandassignittotheglobalobject.

Ifyoudon'tinitializethevariablewhenyoudeclareit,itwillhavethe undefinedvalueuntilyouassignavaluetoit.

vara//typeofa==='undefined'

Youcanredeclarethevariablemanytimes,overridingit:

vara=1

Variables

43

Page 44: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

vara=2

Youcanalsodeclaremultiplevariablesatonceinthesamestatement:

vara=1,b=2

Thescopeistheportionofcodewherethevariableisvisible.

Avariableinitializedwith varoutsideofanyfunctionisassignedtotheglobalobject,hasaglobalscopeandisvisibleeverywhere.Avariableinitializedwith varinsideafunctionisassignedtothatfunction,it'slocalandisvisibleonlyinsideit,justlikeafunctionparameter.

Anyvariabledefinedintoafunctionwiththesamenameofaglobalvariabletakesprecedenceovertheglobalvariable,shadowingit.

It'simportanttounderstandthatablock(identifiedbyapairofcurlybraces)doesnotdefineanewscope.Anewscopeisonlycreatedwhenafunctioniscreated,because varhasnotblockscope,butfunctionscope.

Insideafunction,anyvariabledefinedinitisvisiblethroughoutallthefunctioncode,evenifthevariableisdeclaredattheendofthefunctionitcanstillbereferencedinthebeginning,becauseJavaScriptbeforeexecutingthecodeactuallymovesallvariablesontop(somethingthatiscalledhoisting).Toavoidconfusion,alwaysdeclarevariablesatthebeginningofafunction.

Using letletisanewfeatureintroducedinES2015andit'sessentiallyablockscopedversionofvar.Itsscopeislimitedtotheblock,statementorexpressionwhereit'sdefined,andallthecontainedinnerblocks.

ModernJavaScriptdevelopersmightchoosetoonlyuse letandcompletelydiscardtheuseof var.

If letseemsanobscureterm,justread letcolor='red'asletthecolorberedandallhasmuchmoresense

Defining letoutsideofanyfunction-contraryto var-doesnotcreateaglobalvariable.

Using const

Variables

44

Page 45: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Variablesdeclaredwith varor letcanbechangedlateronintheprogram,andreassigned.Aoncea constisinitialized,itsvaluecanneverbechangedagain,anditcan'tbereassignedtoadifferentvalue.

consta='test'

Wecan'tassignadifferentliteraltothe aconst.Wecanhowevermutate aifit'sanobjectthatprovidesmethodsthatmutateitscontents.

constdoesnotprovideimmutability,justmakessurethatthereferencecan'tbechanged.

consthasblockscope,sameas let.

ModernJavaScriptdevelopersmightchoosetoalwaysuse constforvariablesthatdon'tneedtobereassignedlaterintheprogram.

Why?Becauseweshouldalwaysusethesimplestconstructavailabletoavoidmakingerrorsdowntheroad.

Variables

45

Page 46: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TypesYoumightsometimesreadthatJSisuntyped,butthat'sincorrect.It'struethatyoucanassignallsortsofdifferenttypestoavariable,butJavaScripthastypes.Inparticular,itprovidesprimitivetypes,andobjecttypes.

PrimitivetypesPrimitivetypesare

NumbersStringsBooleans

Andtwospecialtypes:

nullundefined

Let'sseethemindetailinthenextsections.

NumbersInternally,JavaScripthasjustonetypefornumbers:everynumberisafloat.

Anumericliteralisanumberrepresentedinthesourcecode,amddependingonhowit'swritten,itcanbeanintegerliteralorafloatingpointliteral.

Integers:

10

5354576767321

0xCC//hex

Floats:

3.14

.1234

5.2e4//5.2*10^4

Strings

Types

46

Page 47: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Astringtypeisasequenceofcharacters.It'sdefinedinthesourcecodeasastringliteral,whichisenclosedinquotesordoublequotes

'Astring'

"Anotherstring"

Stringscanspanacrossmultiplelinesbyusingthebackslash

"A\

string"

Astringcancontainescapesequencesthatcanbeinterpretedwhenthestringisprinted,like\ntocreateanewline.Thebackslashisalsousefulwhenyouneedtoenterforexampleaquoteinastringenclosedinquotes,topreventthechartobeinterpretedasaclosingquote:

'I\'madeveloper'

Stringscanbejoinedusingthe+operator:

"A"+"string"

Templatestrings

IntroducedinES2015,templatestringsarestringliteralsthatallowamorepowerfulwaytodefinestrings.

`astring`

Youcanperformstringsubstitution,embeddingtheresultofanyJSexpression:

`astringwith${something}`

`astringwith${something+somethingElse}`

`astringwith${obj.something()}`

Youcanhavemultilinestringseasily:

`astring

with

${something}`

Booleans

Types

47

Page 48: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

JavaScriptdefinestworeservedwordsforbooleans:trueandfalse.Manycomparisionoperations == === < >(andsoon)returneitheroneortheother.

if, whilestatementsandothercontrolstructuresusebooleanstodeterminetheflowoftheprogram.

Theydon'tjustaccepttrueorfalse,butalsoaccepttruthyandfalsyvalues.

Falsyvalues,valuesinterpretedasfalse,are

0

-0

NaN

undefined

null

''//emptystring

Alltherestisconsideredatruthyvalue.

nullnullisaspecialvaluethatindicatestheabsenceofavalue.

It'sacommonconceptinotherlanguagesaswell,canbeknownas nilor NoneinPythonforexample.

undefinedundefinedindicatesthatavariablehasnotbeeninitializedandthevalueisabsent.

It'scommonlyreturnedbyfunctionswithno returnvalue.Whenafunctionacceptsaparameterbutthat'snotsetbythecaller,it'sundefined.

Todetectifavalueis undefined,youusetheconstruct:

typeofvariable==='undefined'

ObjecttypesAnythingthat'snotaprimitivetypeisanobjecttype.

Types

48

Page 49: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Functions,arraysandwhatwecallobjectsareobjecttypes.Theyarespecialontheirown,buttheyinheritmanypropertiesofobjects,likehavingpropertiesandalsohavingmethodsthatcanactonthoseproperties.

Types

49

Page 50: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ExpressionsExpressionsareunitsofcodethatcanbeevaluatedandresolvetoavalue.ExpressionsinJScanbedividedincategories.

ArithmeticexpressionsUnderthiscategorygoallexpressionsthatevaluatetoanumber:

1/2

i++

i-=2

i*2

StringexpressionsExpressionsthatevaluatetoastring:

'A'+'string'

'A'+='string'

PrimaryexpressionsUnderthiscategorygovariablereferences,literalsandconstants:

2

0.02

'something'

true

false

this//thecurrentobject

undefined

i//whereiisavariableoraconstant

butalsosomelanguagekeywords:

function

class

function*//thegeneratorfunction

yield//thegeneratorpauser/resumer

yield*//delegatetoanothergeneratororiterator

Expressions

50

Page 51: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

asyncfunction*//asyncfunctionexpression

await//asyncfunctionpause/resume/waitforcompletion

/pattern/i//regex

()//grouping

Arrayandobjectinitializersexpressions

[]//arrayliteral

{}//objectliteral

[1,2,3]

{a:1,b:2}

{a:{b:1}}

LogicalexpressionsLogicalexpressionsmakeuseoflogicaloperatorsandresolvetoabooleanvalue:

a&&b

a||b

!a

Left-hand-sideexpressions

new//createaninstanceofaconstructor

super//callstheparentconstructor

...obj//expressionusingthespreadoperator

Propertyaccessexpressions

object.property//referenceaproperty(ormethod)ofanobject

object[property]

object['property']

Objectcreationexpressions

newobject()

newa(1)

newMyRectangle('name',2,{a:4})

Expressions

51

Page 52: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Functiondefinitionexpressions

function(){}

function(a,b){returna*b}

(a,b)=>a*b

a=>a*2

()=>{return2}

InvocationexpressionsThesyntaxforcallingafunctionormethod

a.x(2)

window.resize()

Expressions

52

Page 53: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

PrototypalinheritanceJavaScriptisquiteuniqueinthepopularprogramminglanguageslandscapebecauseofitsusageofprototypalinheritance.Let'sfindoutwhatthatmeans

JavaScriptisquiteuniqueinthepopularprogramminglanguageslandscapebecauseofitsusageofprototypalinheritance.

Whilemostobject-orientedlanguagesuseaclass-basedinheritancemodel,JavaScriptisbasedontheprototypeinheritancemodel.

Whatdoesthismean?

EverysingleJavaScriptobjecthasaproperty,called prototype,whichpointstoadifferentobject.

Thisdifferentobjectistheobjectprototype.

Ourobjectusesthatobjectprototypetoinheritpropertiesandmethods.

Sayyouhaveanobjectcreatedusingtheobjectliteralsyntax:

constcar={}

oronecreatedwiththe newObjectsyntax:

constcar=newObject()

inanycase,theprototypeof caris Object:

Ifyouinitializeanarray,whichisanobject:

constlist=[]

//or

constlist=newArray()

theprototypeis Array.

Youcanverifythisbycheckingthe __proto__getter:

car.__proto__==Object.prototype//true

car.__proto__==newObject().__proto__//true

list.__proto__==Object.prototype//false

list.__proto__==Array.prototype//true

list.__proto__==newArray().__proto__//true

Prototypalinheritance

53

Page 54: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Iusethe __proto__propertyhere,whichisnon-standardbutwidelyimplementedinbrowsers.Amorereliablewaytogetaprototypeistouse Object.getPrototypeOf(newObject())

Allthepropertiesandmethodsoftheprototypeareavailabletotheobjectthathasthatprototype:

Object.prototypeisthebaseprototypeofalltheobjects:

Array.prototype.__proto__==Object.prototype

Ifyouwonderwhat'stheprototypeoftheObject.prototype,thereisnoprototype.It'saspecialsnowflake❄ .

Theaboveexampleyousawisanexampleoftheprototypechainatwork.

IcanmakeanobjectthatextendsArrayandanyobjectIinstantiateusingit,willhaveArrayandObjectinitsprototypechainandinheritpropertiesandmethodsfromalltheancestors.

Inadditiontousingthe newoperatortocreateanobject,orusingtheliteralssyntaxforobjectsandarrays,youcaninstantiateanobjectusing Object.create().

Thefirstargumentpassedistheobjectusedasprototype:

Prototypalinheritance

54

Page 55: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

constcar=Object.create({})

constlist=Object.create(Array)

Youcanchecktheprototypeofanobjectusingthe isPrototypeOf()method:

Array.isPrototypeOf(list)//true

Payattentionbecauseyoucaninstantiateanarrayusing

constlist=Object.create(Array.prototype)

andinthiscase Array.isPrototypeOf(list)isfalse,whileArray.prototype.isPrototypeOf(list)istrue.

Prototypalinheritance

55

Page 56: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ClassesIn2015theECMAScript6(ES6)standardintroducedclasses.Learnallaboutthem

In2015theECMAScript6(ES6)standardintroducedclasses.

Beforethat,JavaScriptonlyhadaquiteuniquewaytoimplementinheritance.Itsprototypalinheritance,whileinmyopiniongreat,wasdifferentfromanyotherpopularprogramminglanguage.

PeoplecomingfromJavaorPythonorotherlanguageshadahardtimeunderstandingtheintricaciesofprototypalinheritance,sotheECMAScriptcommitteedecidedtointroduceasyntacticsugarontopofthem,andresemblehowclasses-basedinheritanceworksinotherpopularimplementations.

Thisisimportant:JavaScriptunderthehoodsisstillthesame,andyoucanaccessanobjectprototypeintheusualway.

AclassdefinitionThisishowaclasslooks.

classPerson{

constructor(name){

this.name=name

}

hello(){

return'Hello,Iam'+this.name+'.'

}

}

Aclasshasanidentifier,whichwecanusetocreatenewobjectsusing newClassIdentifier().

Whentheobjectisinitialized,the constructormethodiscalled,withanyparameterspassed.

Aclassalsohasasmanymethodsasitneeds.Inthiscase helloisamethodandcanbecalledonallobjectsderivedfromthisclass:

constflavio=newPerson('Flavio')

flavio.hello()

Classes

56

Page 57: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ClassesinheritanceAclasscanextendanotherclass,andobjectsinitializedusingthatclassinheritallthemethodsofbothclasses.

Iftheinheritedclasshasamethodwiththesamenameasoneoftheclasseshigherinthehierarchy,theclosestmethodtakesprecedence:

classProgrammerextendsPerson{

hello(){

returnsuper.hello()+'Iamaprogrammer.'

}

}

constflavio=newProgrammer('Flavio')

flavio.hello()

(theaboveprogramprints"Hello,IamFlavio.Iamaprogrammer.")

Classesdonothaveexplicitclassvariabledeclarations,butyoumustinitializeanyvariableintheconstructor.

Insideaclass,youcanreferencetheparentclasscalling super().

StaticmethodsNormallymethodsaredefinedontheinstance,notontheclass.

Staticmethodsareexecutedontheclassinstead:

classPerson{

staticgenericHello(){

return'Hello'

}

}

Person.genericHello()//Hello

PrivatemethodsJavaScriptdoesnothaveabuilt-inwaytodefineprivateorprotectedmethods.

Thereareworkarounds,butIwon'tdescribethemhere.

Classes

57

Page 58: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

GettersandsettersYoucanaddmethodsprefixedwith getor settocreateagetterandsetter,whicharetwodifferentpiecesofcodethatareexecutebasedonwhatyouaredoing:accessingthevariable,ormodifyingitsvalue.

classPerson{

constructor(name){

this.name=name

}

setname(value){

this.name=value

}

getname(){

returnthis.name

}

}

Ifyouonlyhaveagetter,thepropertycannotbeset,andanyattemptatdoingsowillbeignored:

classPerson{

constructor(name){

this.name=name

}

getname(){

returnthis.name

}

}

Ifyouonlyhaveasetter,youcanchangethevaluebutnotaccessitfromtheoutside:

classPerson{

constructor(name){

this.name=name

}

setname(value){

this.name=value

}

}

Classes

58

Page 59: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Classes

59

Page 60: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ExceptionsWhenthecoderunsintoanunexpectedproblem,theJavaScriptidiomaticwaytohandlethissituationisthroughexceptions

Whenthecoderunsintoanunexpectedproblem,theJavaScriptidiomaticwaytohandlethissituationisthroughexceptions.

CreatingexceptionsAnexceptioniscreatedusingthe throwkeyword:

throwvalue

where valuecanbeanyJavaScriptvalueincludingastring,anumberoranobject.

AssoonasJavaScriptexecutesthisline,thenormalprogramflowishaltedandthecontrolisheldbacktothenearestexceptionhandler.

HandlingexceptionsAnexceptionhandlerisa try/ catchstatement.

Anyexceptionraisedinthelinesofcodeincludedinthe tryblockishandledinthecorresponding catchblock:

try{

//linesofcode

}catch(e){

}

einthisexampleistheexceptionvalue.

Youcanaddmultiplehandlers,thatcancatchdifferentkindsoferrors.

finally

Exceptions

60

Page 61: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TocompletethisstatementJavaScripthasanotherstatementcalled finally,whichcontainscodethatisexecutedregardlessoftheprogramflow,iftheexceptionwashandledornot,iftherewasanexceptionoriftherewasn't:

try{

//linesofcode

}catch(e){

}finally{

}

Youcanuse finallywithouta catchblock,toserveasawaytocleanupanyresourceyoumighthaveopenedinthe tryblock,likefilesornetworkrequests:

try{

//linesofcode

}finally{

}

Nested tryblockstryblockscanbenested,andanexceptionisalwayshandledinthenearestcatchblock:

try{

//linesofcode

try{

//otherlinesofcode

}finally{

//otherlinesofcode

}

}catch(e){

}

Ifanexceptionisraisedintheinner try,it'shandledintheouter catchblock.

Exceptions

61

Page 62: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

SemicolonsJavaScriptsemicolonsareoptional.Ipersonallylikeavoidingusingsemicolonsinmycode,butmanypeoplepreferthem.

SemicolonsinJavaScriptdividethecommunity.Someprefertousethemalways,nomatterwhat.Othersliketoavoidthem.

Afterusingsemicolonsforyears,inthefallof2017Idecidedtotryavoidingthemasneeded,andIdidsetupPrettiertoautomaticallyremovesemicolonsfrommycode,unlessthereisaparticularcodeconstructthatrequiresthem.

NowIfinditnaturaltoavoidsemicolons,Ithinkthecodelooksbetterandit'scleanertoread.

ThisisallpossiblebecauseJavaScriptdoesnotstrictlyrequiresemicolons.Whenthereisaplacewhereasemicolonwasneeded,itaddsitbehindthescenes.

TheprocessthatdoesthisiscalledAutomaticSemicolonInsertion.

It'simportanttoknowtherulesthatpowersemicolons,toavoidwritingcodethatwillgeneratebugsbecausedoesnotbehavelikeyouexpect.

TherulesofJavaScriptAutomaticSemicolonInsertionTheJavaScriptparserwillautomaticallyaddasemicolonwhen,duringtheparsingofthesourcecode,itfindstheseparticularsituations:

1. whenthenextlinestartswithcodethatbreaksthecurrentone(codecanspawnonmultiplelines)

2. whenthenextlinestartswitha },closingthecurrentblock3. whentheendofthesourcecodefileisreached4. whenthereisa returnstatementonitsownline5. whenthereisa breakstatementonitsownline6. whenthereisa throwstatementonitsownline7. whenthereisa continuestatementonitsownline

ExamplesofcodethatdoesnotdowhatyouthinkBasedonthoserules,herearesomeexamples.

Semicolons

62

Page 63: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Takethis:

consthey='hey'

constyou='hey'

constheyYou=hey+''+you

['h','e','y'].forEach((letter)=>console.log(letter))

You'llgettheerror UncaughtTypeError:Cannotreadproperty'forEach'ofundefinedbecausebasedonrule 1JavaScripttriestointerpretthecodeas

consthey='hey';

constyou='hey';

constheyYou=hey+''+you['h','e','y'].forEach((letter)=>console.log(letter))

Suchpieceofcode:

(1+2).toString()

prints "3".

consta=1

constb=2

constc=a+b

(a+b).toString()

insteadraisesa TypeError:bisnotafunctionexception,becauseJavaScripttriestointerpretitas

consta=1

constb=2

constc=a+b(a+b).toString()

Anotherexamplebasedonrule4:

(()=>{

return

{

color:'white'

}

})()

Semicolons

63

Page 64: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

You'dexpectthereturnvalueofthisimmediately-invokedfunctiontobeanobjectthatcontainsthe colorproperty,butit'snot.Instead,it's undefined,becauseJavaScriptinsertsasemicolonafter return.

Insteadyoushouldputtheopeningbracketrightafter return:

(()=>{

return{

color:'white'

}

})()

You'dthinkthiscodeshows'0'inanalert:

1+1

-1+1===0?alert(0):alert(2)

butitshows2instead,becauseJavaScriptperrule1interpretsitas:

1+1-1+1===0?alert(0):alert(2)

ConclusionBecareful.Somepeopleareveryopinionatedonsemicolons.Idon'tcarehonestly,thetoolgivesustheoptionnottouseit,sowecanavoidsemicolons.

I'mnotsuggestinganything,otherthanpickingyourowndecision.

Wejustneedtopayabitofattention,evenifmostofthetimesthosebasicscenariosnevershowupinyourcode.

Picksomerules:

becarefulwith returnstatements.Ifyoureturnsomething,additonthesamelineasthereturn(samefor break, throw, continue)neverstartalinewithparentheses,thosemightbeconcatenatedwiththepreviouslinetoformafunctioncall,orarrayelementreference

Andultimately,alwaystestyourcodetomakesureitdoeswhatyouwant

Semicolons

64

Page 65: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Semicolons

65

Page 66: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

QuotesAnoverviewofthequotesallowedinJavaScriptandtheiruniquefeatures

JavaScriptallowsyoutouse3typesofquotes:

singlequotesdoublequotesbackticks

Thefirst2areessentiallythesame:

consttest='test'

constbike="bike"

There'slittletonodifferenceinusingoneortheother.Theonlydifferenceliesinhavingtoescapethequotecharacteryouusetodelimitthestring:

consttest='test'

consttest='te\'st'

consttest='te"st'

consttest="te\"st"

consttest="te'st"

Therearevariousstyleguidesthatrecommendalwaysusingonestylevstheother.

Ipersonallyprefersinglequotesallthetime,andusedoublequotesonlyinHTML.

BackticksarearecentadditiontoJavaScript,sincetheywereintroducedwithES6in2015.

Theyhaveauniquefeature:theyallowmultilinestrings.

Multilinestringsarealsopossibleusingregularstrings,usingescapecharacters:

constmultilineString='Astring\nonmultiplelines'

Usingbackticks,youcanavoidusinganescapecharacter:

constmultilineString=`Astring

onmultiplelines`

Notjustthat.Youcaninterpolatevariablesusingthe ${}syntax:

constmultilineString=`Astring

Quotes

66

Page 67: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

on${1+1}lines`

ThosearecalledTemplateLiterals.

Quotes

67

Page 68: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TemplateLiteralsIntroducedinES2015,akaES6,TemplateLiteralsofferanewwaytodeclarestrings,butalsosomenewinterestingconstructswhicharealreadywidelypopular.

IntroductiontoTemplateLiteralsTemplateLiteralsareanewES2015/ES6featurethatallowyoutoworkwithstringsinanovelwaycomparedtoES5andbelow.

Thesyntaxatafirstglanceisverysimple,justusebackticksinsteadofsingleordoublequotes:

consta_string=`something`

Theyareuniquebecausetheyprovidealotoffeaturesthatnormalstringsbuiltwithquotes,inparticular:

theyofferagreatsyntaxtodefinemultilinestringstheyprovideaneasywaytointerpolatevariablesandexpressionsinstringstheyallowtocreateDSLswithtemplatetags

Let'sdiveintoeachoftheseindetail.

MultilinestringsPre-ES6,tocreateastringspannedovertwolinesyouhadtousethe \characterattheendofaline:

conststring='firstpart\

secondpart'

Thisallowstocreateastringon2lines,butit'srenderedonjustoneline:

firstpartsecondpart

Torenderthestringonmultiplelinesaswell,youexplicitlyneedtoadd \nattheendofeachline,likethis:

conststring='firstline\n\

TemplateLiterals

68

Page 69: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

secondline'

or

conststring='firstline\n'+

'secondline'

Templateliteralsmakemultilinestringsmuchsimpler.

Onceatemplateliteralisopenedwiththebacktick,youjustpressentertocreateanewline,withnospecialcharacters,andit'srenderedas-is:

conststring=`Hey

this

string

isawesome!`

Keepinmindthatspaceismeaningful,sodoingthis:

conststring=`First

Second`

isgoingtocreateastringlikethis:

First

Second

aneasywaytofixthisproblemisbyhavinganemptyfirstline,andappendingthetrim()methodrightaftertheclosingbacktick,whichwilleliminateanyspacebeforethefirstcharacter:

conststring=`

First

Second`.trim()

InterpolationTemplateliteralsprovideaneasywaytointerpolatevariablesandexpressionsintostrings.

Youdosobyusingthe ${...}syntax:

constvar='test'

TemplateLiterals

69

Page 70: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

conststring=`something${var}`//somethingtest

insidethe ${}youcanaddanything,evenexpressions:

conststring=`something${1+2+3}`

conststring2=`something${foo()?'x':'y'}`

TemplatetagsTaggedtemplatesisonefeaturesthatmightsoundlessusefulatfirstforyou,butit'sactuallyusedbylotsofpopularlibrariesaround,likeStyledComponentsorApollo,theGraphQLclient/serverlib,soit'sessentialtounderstandhowitworks.

InStyledComponentstemplatetagsareusedtodefineCSSstrings:

constButton=styled.button`

font-size:1.5em;

background-color:black;

color:white;

`;

InApollotemplatetagsareusedtodefineaGraphQLqueryschema:

constquery=gql`

query{

...

}

`

The styled.buttonand gqltemplatetagshighlightedinthoseexamplesarejustfunctions:

functiongql(literals,...expressions){

}

thisfunctionreturnsastring,whichcanbetheresultofanykindofcomputation.

literalsisanarraycontainingthetemplateliteralcontenttokenizedbytheexpressionsinterpolations.

expressionscontainsalltheinterpolations.

Ifwetakeanexampleabove:

TemplateLiterals

70

Page 71: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

conststring=`something${1+2+3}`

literalsisanarraywithtwoitems.Thefirstis something,thestringuntilthefirstinterpolation,andthesecondisanemptystring,thespacebetwenetheendofthefirstinterpolation(weonlyhaveone)andtheendofthestring.

expressionsinthiscaseisanarraywithasingleitem, 6.

Amorecomplexexampleis:

conststring=`something

another${'x'}

newline${1+2+3}

test`

inthiscase literalsisanarraywherethefirstitemis:

`something

another`

thesecondis:

`

newline`

andthethirdis:

`

test`

expressionsinthiscaseisanarraywithtwoitems, xand 6.

Thefunctionthatispassedthosevaluescandoanythingwiththem,andthisisthepowerofthiskindfeature.

Themostsimpleexampleisreplicatingwhatthestringinterpolationdoes,bysimplyjoiningliteralsand expressions:

constinterpolated=interpolate`Ipaid${10}€`

andthisishow interpolateworks:

functioninterpolate(literals,...expressions){

letstring=``

TemplateLiterals

71

Page 72: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

for(const[i,val]ofexpressions){

string+=literals[i]+val

}

string+=literals[literals.length-1]

returnstring

}

TemplateLiterals

72

Page 73: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

FunctionsLearnallaboutfunctions,fromthegeneraloverviewtothetinydetailsthatwillimprovehowyouusethem

IntroductionEverythinginJavaScripthappensinfunctions.

Afunctionisablockofcode,selfcontained,thatcanbedefinedonceandrunanytimesyouwant.

Afunctioncanoptionallyacceptparameters,andreturnsonevalue.

FunctionsinJavaScriptareobjects,aspecialkindofobjects:functionobjects.Theirsuperpowerliesinthefactthattheycanbeinvoked.

Inaddition,functionsaresaidtobefirstclassfunctionsbecausetheycanbeassignedtoavalue,andtheycanbepassedasargumentsandusedasareturnvalue.

Syntax

Functions

73

Page 74: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Let'sstartwiththe"old",pre-ES6/ES2015syntax.Here'safunctiondeclaration:

functiondosomething(foo){

//dosomething

}

(now,inpostES6/ES2015world,referredasaregularfunction)

Functionscanbeassignedtovariables(thisiscalledafunctionexpression):

constdosomething=function(foo){

//dosomething

}

Namedfunctionexpressionsaresimilar,butplaynicerwiththestackcalltrace,whichisusefulwhenanerroroccurs-itholdsthenameofthefunction:

constdosomething=functiondosomething(foo){

//dosomething

}

ES6/ES2015introducedarrowfunctions,whichareespeciallynicetousewhenworkingwithinlinefunctions,asparametersorcallbacks:

constdosomething=foo=>{

//dosomething

}

Arrowfunctionshaveanimportantdifferencefromtheotherfunctiondefinitionsabove,we'llseewhichonelaterasit'sanadvancedtopic.

ParametersAfunctioncanhaveoneormoreparameters.

constdosomething=()=>{

//dosomething

}

constdosomethingElse=foo=>{

//dosomething

}

constdosomethingElseAgain=(foo,bar)=>{

//dosomething

Functions

74

Page 75: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

}

StartingwithES6/ES2015,functionscanhavedefaultvaluesfortheparameters:

constdosomething=(foo=1,bar='hey')=>{

//dosomething

}

Thisallowsyoutocallafunctionwithoutfillingalltheparameters:

dosomething(3)

dosomething()

ES2018introducedtrailingcommasforparameters,afeaturethathelpsreducingbugsduetomissingcommaswhenmovingaroundparameters(e.g.movingthelastinthemiddle):

constdosomething=(foo=1,bar='hey')=>{

//dosomething

}

dosomething(2,'ho!')

Youcanwrapallyourargumentsinanarray,andusethespreadoperatorwhencallingthefunction:

constdosomething=(foo=1,bar='hey')=>{

//dosomething

}

constargs=[2,'ho!']

dosomething(...args)

Withmanyparameters,rememberingtheordercanbedifficult.Usingobjects,destructuringallowstokeeptheparameternames:

constdosomething=({foo=1,bar='hey'})=>{

//dosomething

console.log(foo)//2

console.log(bar)//'ho!'

}

constargs={foo:2,bar:'ho!'}

dosomething(args)

Returnvalues

Functions

75

Page 76: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Everyfunctionreturnsavalue,whichbydefaultis undefined.

Anyfunctionisterminatedwhenitslinesofcodeend,orwhentheexecutionflowfindsareturnkeyword.

WhenJavaScriptencountersthiskeyworditexitsthefunctionexecutionandgivescontrolbacktoitscaller.

Ifyoupassavalue,thatvalueisreturnedastheresultofthefunction:

constdosomething=()=>{

return'test'

}

constresult=dosomething()//result==='test'

Youcanonlyreturnonevalue.

Tosimulatereturningmultiplevalues,youcanreturnanobjectliteral,oranarray,anduseadestructuringassignmentwhencallingthefunction.

Usingarrays:

Functions

76

Page 77: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Usingobjects:

NestedfunctionsFunctionscanbedefinedinsideotherfunctions:

constdosomething=()=>{

constdosomethingelse=()=>{}

dosomethingelse()

return'test'

}

Functions

77

Page 78: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thenestedfunctionisscopedtotheoutsidefunction,andcannotbecalledfromtheoutside.

ObjectMethodsWhenusedasobjectproperties,functionsarecalledmethods:

constcar={

brand:'Ford',

model:'Fiesta',

start:function(){

console.log(`Started`)

}

}

car.start()

thisinArrowFunctionsThere'sanimportantbehaviorofArrowFunctionsvsregularFunctionswhenusedasobjectmethods.Considerthisexample:

constcar={

brand:'Ford',

model:'Fiesta',

start:function(){

console.log(`Started${this.brand}${this.model}`)

},

stop:()=>{

console.log(`Stopped${this.brand}${this.model}`)

}

}

The stop()methoddoesnotworkasyouwouldexpect.

Functions

78

Page 79: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thisisbecausethehandlingof thisisdifferentinthetwofunctionsdeclarationsstyle. thisinthearrowfunctionreferstotheenclosingfunctioncontext,whichinthiscaseisthe windowobject:

this,whichreferstothehostobjectusing function()

Functions

79

Page 80: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thisimpliesthatarrowfunctionsarenotsuitabletobeusedforobjectmethodsandconstructors(arrowfunctionconstructorswillactuallyraisea TypeErrorwhencalled).

IIFE,ImmediatelyInvocatedFunctionExpressionsAnIIFEisafunctionthat'simmediatelyexecutedrightafteritsdeclaration:

;(functiondosomething(){

console.log('executed')

})()

Youcanassigntheresulttoavariable:

constsomething=(functiondosomething(){

return'something'

})()

Theyareveryhandy,asyoudon'tneedtoseparatelycallthefunctionafteritsdefinition.

FunctionHoistingJavaScriptbeforeexecutingyourcodereordersitaccordingtosomerules.

Functionsinparticulararemovedatthetopoftheirscope.Thisiswhyit'slegaltowrite

dosomething()

functiondosomething(){

console.log('didsomething')

}

Internally,JavaScriptmovesthefunctionbeforeitscall,alongwithalltheotherfunctionsfoundinthesamescope:

Functions

80

Page 81: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

functiondosomething(){

console.log('didsomething')

}

dosomething()

Now,ifyouusenamedfunctionexpressions,sinceyou'reusingvariablessomethingdifferenthappens.Thevariabledeclarationishoisted,butnotthevalue,sonotthefunction.

dosomething()

constdosomething=functiondosomething(){

console.log('didsomething')

}

Notgoingtowork:

Thisisbecausewhathappensinternallyis:

constdosomething

dosomething()

dosomething=functiondosomething(){

console.log('didsomething')

}

Thesamehappensfor letdeclarations. vardeclarationsdonotworkeither,butwithadifferenterror:

Functions

81

Page 82: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thisisbecause vardeclarationsarehoistedandinitializedwith undefinedasavalue,whileconstand letarehoistedbutnotinitialized.

Functions

82

Page 83: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ArrowFunctionsArrowFunctionsareoneofthemostimpactfulchangesinES6/ES2015,andtheyarewidelyusednowadays.Theyslightlydifferfromregularfunctions.Findouthow

ArrowfunctionswereintroducedinES6/ECMAScript2015,andsincetheirintroductiontheychangedforeverhowJavaScriptcodelooks(andworks).

Inmyopinionthischangewassowelcomingthatyounowrarelyseeinmoderncodebasestheusageofthe functionkeyword.

Visually,it’sasimpleandwelcomechange,whichallowsyoutowritefunctionswithashortersyntax,from:

constmyFunction=functionfoo(){

//...

}

to

constmyFunction=()=>{

//...

}

Ifthefunctionbodycontainsjustasinglestatement,youcanomittheparenthesesandwriteallonasingleline:

constmyFunction=()=>doSomething()

Parametersarepassedintheparentheses:

constmyFunction=(param1,param2)=>doSomething(param1,param2)

Ifyouhaveone(andjustone)parameter,youcouldomittheparenthesescompletely:

constmyFunction=param=>doSomething(param)

Thankstothisshortsyntax,arrowfunctionsencouragetheuseofsmallfunctions.

Implicitreturn

ArrowFunctions

83

Page 84: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Arrowfunctionsallowyoutohaveanimplicitreturn:valuesarereturnedwithouthavingtousethe returnkeyword.

Itworkswhenthereisaon-linestatementinthefunctionbody:

constmyFunction=()=>'test'

myFunction()//'test'

Anotherexample,returninganobject(remembertowrapthecurlybracketsinparenthesestoavoiditbeingconsideredthewrappingfunctionbodybrackets):

constmyFunction=()=>({value:'test'})

myFunction()//{value:'test'}

How thisworksinarrowfunctionsthisisaconceptthatcanbecomplicatedtograsp,asitvariesalotdependingonthecontextandalsovariesdependingonthemodeofJavaScript(strictmodeornot).

It'simportanttoclarifythisconceptbecausearrowfunctionsbehaveverydifferentlycomparedtoregularfunctions.

Whendefinedasamethodofanobject,inaregularfunction thisreferstotheobject,soyoucando:

constcar={

model:'Fiesta',

manufacturer:'Ford',

fullName:function(){

return`${this.manufacturer}${this.model}`

}

}

calling car.fullName()willreturn "FordFiesta".

The thisscopewitharrowfunctionsisinheritedfromtheexecutioncontext.Anarrowfunctiondoesnotbind thisatall,soitsvaluewillbelookedupinthecallstack,sointhiscode car.fullName()willnotwork,andwillreturnthestring "undefinedundefined":

constcar={

model:'Fiesta',

manufacturer:'Ford',

fullName:()=>{

ArrowFunctions

84

Page 85: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

return`${this.manufacturer}${this.model}`

}

}

Duetothis,arrowfunctionsarenotsuitedasobjectmethods.

Arrowfunctionscannotbeusedasconstructorsaswell,wheninstantiatinganobjectwillraisea TypeError.

Thisiswhereregularfunctionsshouldbeusedinstead,whendynamiccontextisnotneeded.

Thisisalsoaproblemwhenhandlingevents.DOMEventlistenersset thistobethetargetelement,andifyourelyon thisinaneventhandler,aregularfunctionisnecessary:

constlink=document.querySelector('#link')

link.addEventListener('click',()=>{

//this===window

})

constlink=document.querySelector('#link')

link.addEventListener('click',function(){

//this===link

})

ArrowFunctions

85

Page 86: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ClosuresAgentleintroductiontothetopicofclosures,keytounderstandinghowJavaScriptfunctionswork

Ifyou'veeverwrittenafunctioninJavaScript,youalreadymadeuseofclosures.

It'sakeytopictounderstand,whichhasimplicationsonthethingsyoucando.

Whenafunctionisrun,it'sexecutedwiththescopethatwasinplacewhenitwasdefined,andnotwiththestatethat'sinplacewhenitisexecuted.

Thescopebasicallyisthesetofvariableswhicharevisible.

AfunctionremembersitsLexicalScope,andit'sabletoaccessvariablesthatweredefinedintheparentscope.

Inshort,afunctionhasanentirebaggageofvariablesitcanaccess.

Letmeimmediatelygiveanexampletoclarifythis.

constbark=dog=>{

constsay=`${dog}barked!`

;(()=>console.log(say))()

}

bark(`Roger`)

Closures

86

Page 87: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thislogstotheconsole Rogerbarked!,asexpected.

Whatifyouwanttoreturntheactioninstead:

constprepareBark=dog=>{

constsay=`${dog}barked!`

return()=>console.log(say)

}

constbark=prepareBark(`Roger`)

bark()

Thissnippetalsologstotheconsole Rogerbarked!.

Let'smakeonelastexample,whichreuses prepareBarkfortwodifferentdogs:

constprepareBark=dog=>{

constsay=`${dog}barked!`

return()=>{

console.log(say)

}

}

constrogerBark=prepareBark(`Roger`)

constsydBark=prepareBark(`Syd`)

rogerBark()

sydBark()

Thisprints

Rogerbarked!

Sydbarked!

Asyoucansee,thestateofthevariable sayislinkedtothefunctionthat'sreturnedfromprepareBark().

Alsonoticethatweredefineanew sayvariablethesecondtimewecall prepareBark(),butthatdoesnotaffectthestateofthefirst prepareBark()scope.

Thisishowaclosureworks:thefunctionthat'sreturnedkeepstheoriginalstateinitsscope.

Closures

87

Page 88: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ArraysJavaScriptarraysovertimegotmoreandmorefeatures,sometimesit'strickytoknowwhentousesomeconstructvsanother.Thispostaimstoexplainwhatyoushoulduse,asof2018

JavaScriptarraysovertimegotmoreandmorefeatures,sometimesit'strickytoknowwhentousesomeconstructvsanother.Thispostaimstoexplainwhatyoushouldusein2018.

Initializearray

consta=[]

consta=[1,2,3]

consta=Array.of(1,2,3)

consta=Array(6).fill(1)//initanarrayof6itemsofvalue1

Don'tusetheoldsyntax(justuseitfortypedarrays)

consta=newArray()//neveruse

consta=newArray(1,2,3)//neveruse

Arrays

88

Page 89: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Getlengthofthearray

constl=a.length

Iteratingthearray

Every

a.every(f)

Iterates auntil f()returnsfalse

Some

a.some(f)

Iterates auntil f()returnstrue

Iteratethearrayandreturnanewonewiththereturnedresultofafunction

constb=a.map(f)

Iterates aandbuildsanewarraywiththeresultofexecuting f()oneach aelement

Filteranarray

constb=a.filter(f)

Iterates aandbuildsanewarraywithelementsof athatreturnedtruewhenexecutingf()oneach aelement

Reduce

a.reduce((accumulator,currentValue,currentIndex,array)=>{

//...

Arrays

89

Page 90: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

},initialValue)

reduce()executesacallbackfunctiononalltheitemsofthearrayandallowstoprogressivelycomputearesult.If initialValueisspecified, accumulatorinthefirstiterationwillequaltothatvalue.

Example:

;[1,2,3,4].reduce((accumulator,currentValue,currentIndex,array)=>{

returnaccumulator*currentValue

},1)

//iteration1:1*1=>return1

//iteration2:1*2=>return2

//iteration3:2*3=>return6

//iteration4:6*4=>return24

//returnvalueis24

forEach

ES6

a.forEach(f)

Iterates fon awithoutawaytostop

Example:

a.forEach(v=>{

console.log(v)

})

for..of

ES6

for(letvofa){

console.log(v)

}

for

for(leti=0;i<a.length;i+=1){

//a[i]

Arrays

90

Page 91: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

}

Iterates a,canbestoppedusing returnor breakandaniterationcanbeskippedusingcontinue

@@iterator

ES6

Gettingtheiteratorfromanarrayreturnsaniteratorofvalues

consta=[1,2,3]

letit=a[Symbol.iterator]()

console.log(it.next().value)//1

console.log(it.next().value)//2

console.log(it.next().value)//3

.entries()returnsaniteratorofkey/valuepairs

letit=a.entries()

console.log(it.next().value)//[0,1]

console.log(it.next().value)//[1,2]

console.log(it.next().value)//[2,3]

.keys()allowstoiterateonthekeys:

letit=a.keys()

console.log(it.next().value)//0

console.log(it.next().value)//1

console.log(it.next().value)//2

.next()returns undefinedwhenthearrayends.Youcanalsodetectiftheiterationendedbylookingat it.next()whichreturnsa value,donepair. doneisalwaysfalseuntilthelastelement,whichreturns true.

Addingtoanarray

Addattheend

a.push(4)

Arrays

91

Page 92: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Addatthebeginning

a.unshift(0)

a.unshift(-2,-1)

Removinganitemfromanarray

Fromtheend

a.pop()

Fromthebeginning

a.shift()

Atarandomposition

a.splice(0,2)//getthefirst2items

a.splice(3,2)//getthe2itemsstartingfromindex3

Donotuse remove()asitleavesbehindundefinedvalues.

Removeandinsertinplace

a.splice(2,3,2,'a','b')//removes3itemsstartingfrom

//index2,andadds2items,

//stillstartingfromindex2

Joinmultiplearrays

consta=[1,2]

constb=[3,4]

a.concat(b)//1,2,3,4

Lookupthearrayforaspecificelement

Arrays

92

Page 93: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ES5

a.indexOf()

Returnstheindexofthefirstmatchingitemfound,or-1ifnotfound

a.lastIndexOf()

Returnstheindexofthelastmatchingitemfound,or-1ifnotfound

ES6

a.find((element,index,array)=>{

//returntrueorfalse

})

Returnsthefirstitemthatreturnstrue.Returnsundefinedifnotfound.

Acommonlyusedsyntaxis:

a.find(x=>x.id===my_id)

Theabovelinewillreturnthefirstelementinthearraythathas id===my_id.

findIndexreturnstheindexofthefirstitemthatreturnstrue,andifnotfound,itreturnsundefined:

a.findIndex((element,index,array)=>{

//returntrueorfalse

})

ES7

a.includes(value)

Returnstrueif acontains value.

a.includes(value,i)

Returnstrueif acontains valueaftertheposition i.

Arrays

93

Page 94: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Getaportionofanarray

a.slice()

SortthearraySortalphabetically(byASCIIvalue- 0-9A-Za-z)

consta=[1,2,3,10,11]

a.sort()//1,10,11,2,3

constb=[1,'a','Z',3,2,11]

b=a.sort()//1,11,2,3,Z,a

Sortbyacustomfunction

consta=[1,10,3,2,11]

a.sort((a,b)=>a-b)//1,2,3,10,11

Reversetheorderofanarray

a.reverse()

Getastringrepresentationofanarray

a.toString()

Returnsastringrepresentationofanarray

a.join()

Returnsastringconcatenationofthearrayelements.Passaparametertoaddacustomseparator:

a.join(',')

Copyanexistingarraybyvalue

Arrays

94

Page 95: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

constb=Array.from(a)

constb=Array.of(...a)

Copyjustsomevaluesfromanexistingarray

constb=Array.from(a,x=>x%2==0)

Copyportionsofanarrayintothearrayitself,inotherpositions

consta=[1,2,3,4]

a.copyWithin(0,2)//[3,4,3,4]

constb=[1,2,3,4,5]

b.copyWithin(0,2)//[3,4,5,4,5]

//0iswheretostartcopyinginto,

//2iswheretostartcopyingfrom

constc=[1,2,3,4,5]

c.copyWithin(0,2,4)//[3,4,3,4,5]

//4isanendindex

Arrays

95

Page 96: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

LoopsJavaScriptprovidesmanywaytoiteratethroughloops.ThistutorialexplainsallthevariouslooppossibilitiesinmodernJavaScript

IntroductionJavaScriptprovidesmanywaytoiteratethroughloops.Thistutorialexplainseachonewithasmallexampleandthemainproperties.

for

constlist=['a','b','c']

for(leti=0;i<list.length;i++){

console.log(list[i])//value

console.log(i)//index

}

Youcaninterrupta forloopusing breakYoucanfastforwardtothenextiterationofa forloopusing continue

Loops

96

Page 97: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

forEachIntroducedinES5.Givenanarray,youcaniterateoveritspropertiesusing list.forEach():

constlist=['a','b','c']

list.forEach((item,index)=>{

console.log(item)//value

console.log(index)//index

})

//indexisoptional

list.forEach(item=>console.log(item))

unfortunatelyyoucannotbreakoutofthisloop.

do...while

constlist=['a','b','c']

leti=0

do{

console.log(list[i])//value

console.log(i)//index

i=i+1

}while(i<list.length)

Youcaninterrupta whileloopusing break:

do{

if(something)break

}while(true)

andyoucanjumptothenextiterationusing continue:

do{

if(something)continue

//dosomethingelse

}while(true)

while

constlist=['a','b','c']

leti=0

while(i<list.length){

Loops

97

Page 98: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

console.log(list[i])//value

console.log(i)//index

i=i+1

}

Youcaninterrupta whileloopusing break:

while(true){

if(something)break

}

andyoucanjumptothenextiterationusing continue:

while(true){

if(something)continue

//dosomethingelse

}

Thedifferencewith do...whileisthat do...whilealwaysexecuteitscycleatleastonce.

for...in

Iteratesalltheenumerablepropertiesofanobject,givingthepropertynames.

for(letpropertyinobject){

console.log(property)//propertyname

console.log(object[property])//propertyvalue

}

for...of

ES2015introducedthe for...ofloop,whichcombinestheconcisenessofforEachwiththeabilitytobreak:

//iterateoverthevalue

for(constvalueof['a','b','c']){

console.log(value)//value

}

//gettheindexaswell,using`entries()`

for(const[index,value]of['a','b','c'].entries()){

console.log(index)//index

console.log(value)//value

}

Loops

98

Page 99: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Noticetheuseof const.Thisloopcreatesanewscopeineveryiteration,sowecansafelyusethatinsteadof let.

for...invs for...ofThedifferencewith for...inis:

for...ofiteratesoverthepropertyvaluesfor...initeratesthepropertynames

Loops

99

Page 100: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

EventsJavaScriptinthebrowserusesanevent-drivenprogrammingmodel.Everythingstartsbyfollowinganevent.ThisisanintroductiontoJavaScripteventsandhoweventhandlingworks

IntroductionJavaScriptinthebrowserusesanevent-drivenprogrammingmodel.

Everythingstartsbyfollowinganevent.

TheeventcouldbetheDOMisloaded,oranasynchronousrequestthatfinishesfetching,orauserclickinganelementorscrollingthepage,ortheusertypesonthekeyboard.

Therearealotofdifferentkindofevents.

EventhandlersYoucanrespondtoanyeventusinganEventHandler,whichisjustafunctionthat'scalledwhenaneventoccurs.

Events

100

Page 101: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Youcanregistermultiplehandlersforthesameevent,andtheywillallbecalledwhenthateventhappens.

JavaScriptofferthreewaystoregisteraneventhandler:

Inlineeventhandlers

Thisstyleofeventhandlersisveryrarelyusedtoday,duetoitsconstrains,butitwastheonlywayintheJavaScriptearlydays:

<ahref="site.com"onclick="dosomething();">Alink</a>

DOMon-eventhandlers

Thisiscommonwhenanobjecthasatmostoneeventhandler,asthereisnowaytoaddmultiplehandlersinthiscase:

window.onload=()=>{

//windowloaded

}

It'smostcommonlyusedwhenhandlingXHRrequests:

constxhr=newXMLHttpRequest()

xhr.onreadystatechange=()=>{

//..dosomething

}

Youcancheckifanhandlerisalreadyassignedtoapropertyusing if('onsomething'inwindow){}.

Using addEventListener()

Thisisthemodernway.Thismethodallowstoregisterasmanyhandlersasweneed,andit'sthemostpopularyouwillfind:

window.addEventListener('load',()=>{

//windowloaded

})

Thismethodallowstoregisterasmanyhandlersasweneed,andit'sthemostpopularyouwillfind.

Events

101

Page 102: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

NotethatIE8andbelowdidnotsupportthis,andinsteaduseditsown attachEvent()API.Keepitinmindifyouneedtosupportolderbrowsers.

ListeningondifferentelementsYoucanlistenon windowtointercept"global"events,liketheusageofthekeyboard,andyoucanlistenonspecificelementstocheckeventshappeningonthem,likeamouseclickonabutton.

Thisiswhy addEventListenerissometimescalledon window,sometimesonaDOMelement.

TheEventobjectAneventhandlergetsan Eventobjectasthefirstparameter:

constlink=document.getElementById('my-link')

link.addEventListener('click',event=>{

//linkclicked

})

Thisobjectcontainsalotofusefulpropertiesandmethods,like:

target,theDOMelementthatoriginatedtheeventtype,thetypeofeventstopPropagation(),calledtostoppropagatingtheeventintheDOM

(seethefulllist).

Otherpropertiesareprovidedbyspecifickindofevents,as Eventisaninterfacefordifferentspecificevents:

MouseEventKeyboardEventDragEventFetchEvent...andothers

EachofthosehasaMDNpagelinked,soyoucaninspectalltheirproperties.

ForexamplewhenaKeyboardEventhappens,youcancheckwhichkeywaspressed,inarreadableformat( Escape, Enterandsoon)bycheckingthe keyproperty:

window.addEventListener('keydown',event=>{

//keypressed

Events

102

Page 103: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

console.log(event.key)

})

Onamouseeventwecancheckwhichmousebuttonwaspressed:

constlink=document.getElementById('my-link')

link.addEventListener('mousedown',event=>{

//mousebuttonpressed

console.log(event.button)//0=left,2=right

})

EventbubblingandeventcapturingBubblingandcapturingarethe2modelsthateventsusetopropagate.

SupposeyouDOMstructureis

<divid="container">

<button>Clickme</button>

</div>

Youwanttotrackwhenusersclickonthebutton,andyouhave2eventlisteners,oneonbutton,andoneon #container.Remember,aclickonachildelementwillalwayspropagatetoitsparents,unlessyoustopthepropagation(seelater).

Thoseeventlistenerswillbecalledinorder,andthisorderisdeterminedbytheeventbubbling/capturingmodelused.

Bubblingmeansthattheeventpropagatesfromtheitemthatwasclicked(thechild)uptoallitsparenttree,startingfromthenearestone.

Inourexample,thehandleron buttonwillfirebeforethe #containerhandler.

Capturingistheopposite:theoutereventhandlersarefiredbeforethemorespecifichandler,theoneon button.

Bydefaultalleventsbubble.

YoucanchoosetoadopteventcapturingbyapplyingathirdargumenttoaddEventListener,settingitto true:

document.getElementById('container').addEventListener(

'click',

()=>{

//windowloaded

},

Events

103

Page 104: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

true

)

Notethatfirstallcapturingeventhandlersarerun.

Thenallthebubblingeventhandlers.

Theorderfollowsthisprinciple:theDOMgoesthroughallelementsstartingfromtheWindowobject,andgoestofindtheitemthatwasclicked.Whiledoingso,itcallsanyeventhandlerassociatedtotheevent(capturingphase).

Onceitreachesthetarget,itthenrepeatsthejourneyuptotheparentstreeuntiltheWindowobject,callingagaintheeventhandlers(bubblingphase).

StoppingthepropagationAneventonaDOMelementwillbepropagatedtoallitsparentelementstree,unlessit'sstopped.

<html>

<body>

<section>

<aid="my-link"...>

Aclickeventon awillpropagateto sectionandthen body.

Youcanstopthepropagationbycallingthe stopPropagation()methodofanEvent,usuallyattheendoftheeventhandler:

constlink=document.getElementById('my-link')

link.addEventListener('mousedown',event=>{

//processtheevent

//...

event.stopPropagation()

})

PopulareventsHere'salistofthemostcommoneventsyouwilllikelyhandle.

Load

loadisfiredon windowandthe bodyelementwhenthepagehasfinishedloading.

Events

104

Page 105: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Mouseevents

clickfireswhenamousebuttonisclicked. dblclickwhenthemouseisclickedtwotimes.Ofcourseinthiscase clickisfiredjustbeforethisevent. mousedown, mousemoveandmouseupcanbeusedincombinationtotrackdrag-and-dropevents.Becarefulwithmousemove,asitfiresmanytimesduringthemousemovement(seethrottlinglater)

Keyboardevents

keydownfireswhenakeyboardbuttonispressed(andanytimethekeyrepeatswhilethebuttonstayspressed). keyupisfiredwhenthekeyisreleased.

Scroll

The scrolleventisfiredon windoweverytimeyouscrollthepage.Insidetheeventhandleryoucancheckthecurrentscrollingpositionbychecking window.scrollY.

Keepinmindthatthiseventisnotaone-timething.Itfiresalotoftimesduringscrolling,notjustattheendorbeginningofthescrolling,sodon'tdoanyheavycomputationormanipulationinthehandler-usethrottlinginstead.

ThrottlingAswementionedabove, mousemoveand scrollaretwoeventsthatarenotfiredone-timeperevent,butrathertheycontinuouslycalltheireventhandlerfunctionduringallthedurationoftheaction.

Thisisbecausetheyprovidecoordinatessoyoucantrackwhat'shappening.

Ifyouperformacomplexoperationintheeventhandler,youwillaffecttheperformanceandcauseasluggishexperiencetoyoursiteusers.

LibrariesthatprovidethrottlinglikeLodashimplementitin100+linesofcode,tohandleeverypossibleusecase.Asimpleandeasytounderstandimplementationisthis,whichusessetTimeouttocachethescrolleventevery100ms:

letcached=null

window.addEventListener('scroll',event=>{

if(!cached){

setTimeout(()=>{

//youcanaccesstheoriginaleventat`cached`

cached=null

},100)

}

cached=event

Events

105

Page 106: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

})

Events

106

Page 107: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TheEventLoopTheEventLoopisoneofthemostimportantaspectstounderstandaboutJavaScript.Thispostexplainsitinsimpleterms

IntroductionTheEventLoopisoneofthemostimportantaspectstounderstandaboutJavaScript.

I'veprogrammedforyearswithJavaScript,yetI'veneverfullyunderstoodhowthingsworkunderthehoods.It'scompletelyfinetonotknowthisconceptindetail,butasusual,it'shelpfultoknowhowitworks,andalsoyoumightjustbealittlecuriousatthispoint.

ThispostaimstoexplaintheinnerdetailsofhowJavaScriptworkswithasinglethread,andhowithandlesasynchronousfunctions.

YourJavaScriptcoderunssinglethreaded.Thereisjustonethinghappeningatatime.

Thisisalimitationthat'sactuallyveryhelpful,asitsimplifiesalothowyouprogramwithoutworryingaboutconcurrencyissues.

Youjustneedtopayattentiontohowyouwriteyourcodeandavoidanythingthatcouldblockthethread,likesynchronousnetworkcallsorinfiniteloops.

Ingeneral,inmostbrowsersthereisaneventloopforeverybrowsertab,tomakeeveryprocessisolatedandavoidawebpagewithinfiniteloopsorheavyprocessingtoblockyourentirebrowser.

Theenvironmentmanagesmultipleconcurrenteventloops,tohandleAPIcallsforexample.WebWorkersrunintheirowneventloopaswell.

Youmainlyneedtobeconcernedthatyourcodewillrunonasingleeventloop,andwritecodewiththisthinginmindtoavoidblockingit.

BlockingtheeventloopAnyJavaScriptcodethattakestoolongtoreturnbackcontroltotheeventloopwillblocktheexecutionofanyJavaScriptcodeinthepage,evenblocktheUIthread,andtheusercannotclickaround,scrollthepage,andsoon.

TheEventLoop

107

Page 108: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

AlmostalltheI/OprimitivesinJavaScriptarenon-blocking.Networkrequests,Node.jsfilesystemoperations,andsoon.Beingblockingistheexception,andthisiswhyJavaScriptisbasedsomuchoncallbacks,andmorerecentlyonpromisesandasync/await.

ThecallstackThecallstackisaLIFOqueue(LastIn,FirstOut).

Theeventloopcontinuouslychecksthecallstacktoseeifthere'sanyfunctionthatneedstorun.

Whiledoingso,itaddsanyfunctioncallitfindstothecallstackandexecuteseachoneinorder.

Youknowtheerrorstacktraceyoumightbefamiliarwith,inthedebuggerorinthebrowserconsole?Thebrowserlooksupthefunctionnamesinthecallstacktoinformyouwhichfunctionoriginatesthecurrentcall:

TheEventLoop

108

Page 109: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

AsimpleeventloopexplanationLet'spickanexample:

constbar=()=>console.log('bar')

constbaz=()=>console.log('baz')

constfoo=()=>{

console.log('foo')

bar()

baz()

}

foo()

TheEventLoop

109

Page 110: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thiscodeprints

foo

bar

baz

asexpected.

Whenthiscoderuns,first foo()iscalled.Inside foo()wefirstcall bar(),thenwecallbaz().

Atthispointthecallstacklookslikethis:

Theeventlooponeveryiterationlooksifthere'ssomethinginthecallstack,andexecutesit:

TheEventLoop

110

Page 111: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

untilthecallstackisempty.

QueuingfunctionexecutionTheaboveexamplelooksnormal,there'snothingspecialaboutit:JavaScriptfindsthingstoexecute,runstheminorder.

TheEventLoop

111

Page 112: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Let'sseehowtodeferafunctionuntilthestackisclear.

Theusecaseof setTimeout(()=>{}),0)istocallafunction,butexecuteitonceeveryotherfunctioninthecodehasexecuted.

Takethisexample:

constbar=()=>console.log('bar')

constbaz=()=>console.log('baz')

constfoo=()=>{

console.log('foo')

setTimeout(bar,0)

baz()

}

foo()

Thiscodeprints,maybesurprisingly:

foo

baz

bar

Whenthiscoderuns,firstfoo()iscalled.Insidefoo()wefirstcallsetTimeout,passing barasanargument,andweinstructittorunimmediatelyasfastasitcan,passing0asthetimer.Thenwecallbaz().

Atthispointthecallstacklookslikethis:

TheEventLoop

112

Page 113: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Hereistheexecutionorderforallthefunctionsinourprogram:

TheEventLoop

113

Page 114: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Whyisthishappening?

TheMessageQueue

TheEventLoop

114

Page 115: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

WhensetTimeout()iscalled,theBrowserorNode.jsstartthetimer.Oncethetimerexpires,inthiscaseimmediatelyasweput0asthetimeout,thecallbackfunctionisputintheMessageQueue.

TheMessageQueueisalsowhereuser-initiatedeventslikeclickorkeyboardevents,orfetchresponsesarequeuedbeforeyourcodehastheopportunitytoreacttothem.OralsoDOMeventslike onLoad.

Theloopgivesprioritytothecallstack,anditfirstprocesseseverythingitfindsinthecallstack,andoncethere'snothinginthere,itgoestopickupthingsintheeventqueue.

Wedon'thavetowaitforfunctionslike setTimeout,fetchorotherthingstodotheirownwork,becausetheyareprovidedbythebrowser,andtheyliveontheirownthreads.Forexample,ifyousetthe setTimeouttimeoutto2seconds,youdon'thavetowait2seconds-thewaithappenselsewhere.

ES6JobQueueECMAScript2015introducedtheconceptoftheJobQueue,whichisusedbyPromises(alsointroducedinES6/ES2015).It'sawaytoexecutetheresultofanasyncfunctionassoonaspossible,ratherthanbeingputattheendofthecallstack.

Promisesthatresolvebeforethecurrentfunctionendswillbeexecutedrightafterthecurrentfunction.

Ifindnicetheanalogyofarollercoasterrideatanamusementpark:themessagequeueputsyoubackinqueuewithafteralltheotherpeopleinthequeue,whilethejobqueueisthefastpassticketthatletsyoutakeanotherriderightafteryoufinishedthepreviousone.

Example:

constbar=()=>console.log('bar')

constbaz=()=>console.log('baz')

constfoo=()=>{

console.log('foo')

setTimeout(bar,0)

newPromise((resolve,reject)=>

resolve('shouldberightafterbaz,beforebar')

).then(resolve=>console.log(resolve))

baz()

}

foo()

TheEventLoop

115

Page 116: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thisprints

foo

baz

shouldberightafterbaz,beforebar

bar

That'sabigdifferencebetweenPromises(andAsync/await,whichisbuiltonpromises)andplainoldasynchronousfunctionsthrough setTimeout()orotherplatformAPIs.

TheEventLoop

116

Page 117: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

AsynchronousprogrammingandcallbacksJavaScriptissynchronousbydefault,andissinglethreaded.Thismeansthatcodecannotcreatenewthreadsandruninparallel.Findoutwhatasynchronouscodemeansandhowitlookslike

AsynchronicityinProgrammingLanguagesComputersareasynchronousbydesign.

Asynchronousmeansthatthingscanhappenindependentlyofthemainprogramflow.

Inthecurrentconsumercomputers,everyprogramrunsforaspecifictimeslot,andthenitstopsitsexecutiontoletanotherprogramcontinueitsexecution.Thisthingrunsinacyclesofastthat'simpossibletonotice,andwethinkourcomputersrunmanyprogramssimultaneously,butthisisanillusion(exceptonmultiprocessormachines).

Programsinternallyuseinterrupts,asignalthat'semittedtotheprocessortogaintheattentionofthesystem.

Asynchronousprogrammingandcallbacks

117

Page 118: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Iwon'tgointotheinternalsofthis,butjustkeepinmindthatit'snormalforprogramstobeasynchronous,andhalttheirexecutionuntiltheyneedattention,andthecomputercanexecuteotherthingsinthemeantime.Whenaprogramiswaitingforaresponsefromthenetwork,itcannothalttheprocessoruntiltherequestfinishes.

Normally,programminglanguagesaresynchronous,andsomeprovideawaytomanageasynchronicity,inthelanguageorthroughlibraries.C,Java,C#,PHP,Go,Ruby,Swift,Python,theyareallsynchronousbydefault.Someofthemhandleasyncbyusingthreads,spawninganewprocess.

JavaScriptJavaScriptissynchronousbydefaultandissinglethreaded.Thismeansthatcodecannotcreatenewthreadsandruninparallel.

Linesofcodeareexecutedinseries,oneafteranother,forexample:

consta=1

constb=2

constc=a*b

console.log(c)

doSomething()

ButJavaScriptwasborninsidethebrowser,itsmainjob,inthebeginning,wastorespondtouseractions,like onClick, onMouseOver, onChange, onSubmitandsoon.Howcoulditdothiswithasynchronousprogrammingmodel?

Theanswerwasinitsenvironment.ThebrowserprovidesawaytodoitbyprovidingasetofAPIsthatcanhandlethiskindoffunctionality.

Morerecently,Node.jsintroducedanon-blockingI/Oenvironmenttoextendthisconcepttofileaccess,networkcallsandsoon.

CallbacksYoucan'tknowwhenauserisgoingtoclickabutton,sowhatyoudois,youdefineaneventhandlerfortheclickevent.Thiseventhandleracceptsafunction,whichwillbecalledwhentheeventistriggered:

document.getElementById('button').addEventListener('click',()=>{

//itemclicked

})

Asynchronousprogrammingandcallbacks

118

Page 119: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Thisistheso-calledcallback.

Acallbackisasimplefunctionthat'spassedasavaluetoanotherfunction,andwillonlybeexecutedwhentheeventhappens.WecandothisbecauseJavaScripthasfirst-classfunctions,whichcanbeassignedtovariablesandpassedaroundtootherfunctions(calledhigher-orderfunctions)

It'scommontowrapallyourclientcodeina loadeventlisteneronthe windowobject,whichrunsthecallbackfunctiononlywhenthepageisready:

window.addEventListener('load',()=>{

//windowloaded

//dowhatyouwant

})

Callbacksareusedeverywhere,notjustinDOMevents.

Onecommonexampleisbyusingtimers:

setTimeout(()=>{

//runsafter2seconds

},2000)

XHRrequestsalsoacceptacallback,inthisexamplebyassigningafunctiontoapropertythatwillbecalledwhenaparticulareventoccurs(inthiscase,thestateoftherequestchanges):

constxhr=newXMLHttpRequest()

xhr.onreadystatechange=()=>{

if(xhr.readyState===4){

xhr.status===200?console.log(xhr.responseText):console.error('error')

}

}

xhr.open('GET','https://yoursite.com')

xhr.send()

HandlingerrorsincallbacksHowdoyouhandleerrorswithcallbacks?OneverycommonstrategyistousewhatNode.jsadopted:thefirstparameterinanycallbackfunctionistheerrorobject:error-firstcallbacks

Ifthereisnoerror,theobjectis null.Ifthereisanerror,itcontainssomedescriptionoftheerrorandotherinformation.

fs.readFile('/file.json',(err,data)=>{

if(err!==null){

Asynchronousprogrammingandcallbacks

119

Page 120: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

//handleerror

console.log(err)

return

}

//noerrors,processdata

console.log(data)

})

TheproblemwithcallbacksCallbacksaregreatforsimplecases!

Howevereverycallbackaddsalevelofnesting,andwhenyouhavelotsofcallbacks,thecodestartstobecomplicatedveryquickly:

window.addEventListener('load',()=>{

document.getElementById('button').addEventListener('click',()=>{

setTimeout(()=>{

items.forEach(item=>{

//yourcodehere

})

},2000)

})

})

Thisisjustasimple4-levelscode,butI'veseenmuchmorelevelsofnestingandit'snotfun.

Howdowesolvethis?

AlternativestocallbacksStartingwithES6,JavaScriptintroducedseveralfeaturesthathelpuswithasynchronouscodethatdonotinvolveusingcallbacks:

Promises(ES6)Async/Await(ES8)

Asynchronousprogrammingandcallbacks

120

Page 121: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

PromisesPromisesareonewaytodealwithasynchronouscodeinJavaScript,withoutwritingtoomanycallbacksinyourcode.

IntroductiontopromisesApromiseiscommonlydefinedasaproxyforavaluethatwilleventuallybecomeavailable.

Promisesareonewaytodealwithasynchronouscode,withoutwritingtoomanycallbacksinyourcode.

Althoughbeingaroundsinceyears,theyhavebeenstandardizedandintroducedinES2015,andnowtheyhavebeensupersededinES2017byasyncfunctions.

AsyncfunctionsusethepromisesAPIastheirbuildingblock,sounderstandingthemisfundamentalevenifinnewercodeyou'lllikelyuseasyncfunctionsinsteadofpromises.

Howpromiseswork,inbrief

Onceapromisehasbeencalled,itwillstartinpendingstate.Thismeansthatthecallerfunctioncontinuestheexecution,whileitwaitsforthepromisetodoitsownprocessing,andgivethecallerfunctionsomefeedback.

Atthispoint,thecallerfunctionwaitsforittoeitherreturnthepromiseinaresolvedstate,orinarejectedstate,butasyouknowJavaScriptisasynchronous,sothefunctioncontinuesitsexecutionwhilethepromisedoesitwork.

WhichJSAPIusepromises?

Inadditiontoyourowncodeandlibrariescode,promisesareusedbystandardmodernWebAPIssuchas:

theBatteryAPItheFetchAPIServiceWorkers

It'sunlikelythatinmodernJavaScriptyou'llfindyourselfnotusingpromises,solet'sstartdivingrightintothem.

Promises

121

Page 122: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

CreatingapromiseThePromiseAPIexposesaPromiseconstructor,whichyouinitializeusing newPromise():

letdone=true

constisItDoneYet=newPromise(

(resolve,reject)=>{

if(done){

constworkDone='HereisthethingIbuilt'

resolve(workDone)

}else{

constwhy='Stillworkingonsomethingelse'

reject(why)

}

}

)

Asyoucanseethepromisechecksthe doneglobalconstant,andifthat'strue,wereturnaresolvedpromise,otherwisearejectedpromise.

Using resolveand rejectwecancommunicatebackavalue,intheabovecasewejustreturnastring,butitcouldbeanobjectaswell.

ConsumingapromiseInthelastsection,weintroducedhowapromiseiscreated.

Nowlet'sseehowthepromisecanbeconsumedorused.

constisItDoneYet=newPromise(

//...

)

constcheckIfItsDone=()=>{

isItDoneYet

.then((ok)=>{

console.log(ok)

})

.catch((err)=>{

console.error(err)

})

}

Promises

122

Page 123: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Running checkIfItsDone()willexecutethe isItDoneYet()promiseandwillwaitforittoresolve,usingthe thencallback,andifthereisanerror,itwillhandleitinthe catchcallback.

ChainingpromisesApromisecanbereturnedtoanotherpromise,creatingachainofpromises.

AgreatexampleofchainingpromisesisgivenbytheFetchAPI,alayerontopoftheXMLHttpRequestAPI,whichwecanusetogetaresourceandqueueachainofpromisestoexecutewhentheresourceisfetched.

TheFetchAPIisapromise-basedmechanism,andcalling fetch()isequivalenttodefiningourownpromiseusing newPromise().

Exampleofchainingpromises

conststatus=(response)=>{

if(response.status>=200&&response.status<300){

returnPromise.resolve(response)

}

returnPromise.reject(newError(response.statusText))

}

constjson=(response)=>response.json()

fetch('/todos.json')

.then(status)

.then(json)

.then((data)=>{console.log('RequestsucceededwithJSONresponse',data)})

.catch((error)=>{console.log('Requestfailed',error)})

Inthisexample,wecall fetch()togetalistofTODOitemsfromthe todos.jsonfilefoundinthedomainroot,andwecreateachainofpromises.

Running fetch()returnsaresponse,whichhasmanyproperties,andwithinthosewereference:

status,anumericvaluerepresentingtheHTTPstatuscodestatusText,astatusmessage,whichis OKiftherequestsucceeded

responsealsohasa json()method,whichreturnsapromisethatwillresolvewiththecontentofthebodyprocessedandtransformedintoJSON.

Promises

123

Page 124: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Sogiventhosepremises,thisiswhathappens:thefirstpromiseinthechainisafunctionthatwedefined,called status(),thatcheckstheresponsestatusandifit'snotasuccessresponse(between200and299),itrejectsthepromise.

Thisoperationwillcausethepromisechaintoskipallthechainedpromiseslistedandwillskipdirectlytothe catch()statementatthebottom,loggingthe Requestfailedtextalongwiththeerrormessage.

Ifthatsucceedsinstead,itcallsthejson()functionwedefined.Sincethepreviouspromise,whensuccessful,returnedthe responseobject,wegetitasaninputtothesecondpromise.

Inthiscase,wereturnthedataJSONprocessed,sothethirdpromisereceivestheJSONdirectly:

.then((data)=>{

console.log('RequestsucceededwithJSONresponse',data)

})

andwesimplylogittotheconsole.

HandlingerrorsIntheexample,intheprevioussection,wehada catchthatwasappendedtothechainofpromises.

Whenanythinginthechainofpromisesfailsandraisesanerrororrejectsthepromise,thecontrolgoestothenearest catch()statementdownthechain.

newPromise((resolve,reject)=>{

thrownewError('Error')

})

.catch((err)=>{console.error(err)})

//or

newPromise((resolve,reject)=>{

reject('Error')

})

.catch((err)=>{console.error(err)})

Cascadingerrors

Ifinsidethe catch()youraiseanerror,youcanappendasecond catch()tohandleit,andsoon.

Promises

124

Page 125: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

newPromise((resolve,reject)=>{

thrownewError('Error')

})

.catch((err)=>{thrownewError('Error')})

.catch((err)=>{console.error(err)})

Orchestratingpromises

Promise.all()

Ifyouneedtosynchronizedifferentpromises, Promise.all()helpsyoudefinealistofpromises,andexecutesomethingwhentheyareallresolved.

Example:

constf1=fetch('/something.json')

constf2=fetch('/something2.json')

Promise.all([f1,f2]).then((res)=>{

console.log('Arrayofresults',res)

})

.catch((err)=>{

console.error(err)

})

TheES2015destructuringassignmentsyntaxallowsyoutoalsodo

Promise.all([f1,f2]).then(([res1,res2])=>{

console.log('Results',res1,res2)

})

Youarenotlimitedtousing fetchofcourse,anypromiseisgoodtogo.

Promise.race()

Promise.race()runswhenthefirstofthepromisesyoupasstoitresolves,anditrunstheattachedcallbackjustonce,withtheresultofthefirstpromiseresolved.

Example:

constfirst=newPromise((resolve,reject)=>{

setTimeout(resolve,500,'first')

})

constsecond=newPromise((resolve,reject)=>{

Promises

125

Page 126: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

setTimeout(resolve,100,'second')

})

Promise.race([first,second]).then((result)=>{

console.log(result)//second

})

Commonerrors

UncaughtTypeError:undefinedisnotapromise

Ifyougetthe UncaughtTypeError:undefinedisnotapromiseerrorintheconsole,makesureyouuse newPromise()insteadofjust Promise()

Promises

126

Page 127: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

AsyncandAwaitDiscoverthemodernapproachtoasynchronousfunctionsinJavaScript.JavaScriptevolvedinaveryshorttimefromcallbackstoPromises,andsinceES2017asynchronousJavaScriptisevensimplerwiththeasync/awaitsyntax

IntroductionJavaScriptevolvedinaveryshorttimefromcallbackstopromises(ES2015),andsinceES2017asynchronousJavaScriptisevensimplerwiththeasync/awaitsyntax.

Asyncfunctionsareacombinationofpromisesandgenerators,andbasically,theyareahigherlevelabstractionoverpromises.Letmerepeat:async/awaitisbuiltonpromises.

Whywereasync/awaitintroduced?Theyreducetheboilerplatearoundpromises,andthe"don'tbreakthechain"limitationofchainingpromises.

WhenPromiseswereintroducedinES2015,theyweremeanttosolveaproblemwithasynchronouscode,andtheydid,butoverthe2yearsthatseparatedES2015andES2017,itwasclearthatpromisescouldnotbethefinalsolution.

Promiseswereintroducedtosolvethefamouscallbackhellproblem,buttheyintroducedcomplexityontheirown,andsyntaxcomplexity.

Theyweregoodprimitivesaroundwhichabettersyntaxcouldbeexposedtothedevelopers,sowhenthetimewasrightwegotasyncfunctions.

Theymakethecodelooklikeit'ssynchronous,butit'sasynchronousandnon-blockingbehindthescenes.

HowitworksAnasyncfunctionreturnsapromise,likeinthisexample:

constdoSomethingAsync=()=>{

returnnewPromise((resolve)=>{

setTimeout(()=>resolve('Ididsomething'),3000)

})

AsyncandAwait

127

Page 128: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

}

Whenyouwanttocallthisfunctionyouprepend await,andthecallingcodewillstopuntilthepromiseisresolvedorrejected.Onecaveat:theclientfunctionmustbedefinedasasync.Here'sanexample:

constdoSomething=async()=>{

console.log(awaitdoSomethingAsync())

}

AquickexampleThisisasimpleexampleofasync/awaitusedtorunafunctionasynchronously:

constdoSomethingAsync=()=>{

returnnewPromise((resolve)=>{

setTimeout(()=>resolve('Ididsomething'),3000)

})

}

constdoSomething=async()=>{

console.log(awaitdoSomethingAsync())

}

console.log('Before')

doSomething()

console.log('After')

Theabovecodewillprintthefollowingtothebrowserconsole:

Before

After

Ididsomething//after3s

PromiseallthethingsPrependingthe asynckeywordtoanyfunctionmeansthatthefunctionwillreturnapromise.

Evenifit'snotdoingsoexplicitly,itwillinternallymakeitreturnapromise.

Thisiswhythiscodeisvalid:

constaFunction=async()=>{

return'test'

}

AsyncandAwait

128

Page 129: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

aFunction().then(alert)//Thiswillalert'test'

andit'sthesameas:

constaFunction=async()=>{

returnPromise.resolve('test')

}

aFunction().then(alert)//Thiswillalert'test'

ThecodeismuchsimplertoreadAsyoucanseeintheexampleabove,ourcodelooksverysimple.Compareittocodeusingplainpromises,withchainingandcallbackfunctions.

Andthisisaverysimpleexample,themajorbenefitswillarisewhenthecodeismuchmorecomplex.

Forexamplehere'showyouwouldgetaJSONresource,andparseit,usingpromises:

constgetFirstUserData=()=>{

returnfetch('/users.json')//getuserslist

.then(response=>response.json())//parseJSON

.then(users=>users[0])//pickfirstuser

.then(user=>fetch(`/users/${user.name}`))//getuserdata

.then(userResponse=>response.json())//parseJSON

}

getFirstUserData()

Andhereisthesamefunctionalityprovidedusingawait/async:

constgetFirstUserData=async()=>{

constresponse=awaitfetch('/users.json')//getuserslist

constusers=awaitresponse.json()//parseJSON

constuser=users[0]//pickfirstuser

constuserResponse=awaitfetch(`/users/${user.name}`)//getuserdata

constuserData=awaituser.json()//parseJSON

returnuserData

}

getFirstUserData()

Multipleasyncfunctionsinseries

AsyncandAwait

129

Page 130: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Asyncfunctionscanbechainedveryeasily,andthesyntaxismuchmorereadablethanwithplainpromises:

constpromiseToDoSomething=()=>{

returnnewPromise(resolve=>{

setTimeout(()=>resolve('Ididsomething'),10000)

})

}

constwatchOverSomeoneDoingSomething=async()=>{

constsomething=awaitpromiseToDoSomething()

returnsomething+'andIwatched'

}

constwatchOverSomeoneWatchingSomeoneDoingSomething=async()=>{

constsomething=awaitwatchOverSomeoneDoingSomething()

returnsomething+'andIwatchedaswell'

}

watchOverSomeoneWatchingSomeoneDoingSomething().then((res)=>{

console.log(res)

})

Willprint:

IdidsomethingandIwatchedandIwatchedaswell

EasierdebuggingDebuggingpromisesishardbecausethedebuggerwillnotstepoverasynchronouscode.

Async/awaitmakesthisveryeasybecausetothecompilerit'sjustlikesynchronouscode.

AsyncandAwait

130

Page 131: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

LoopsandScopeThereisonefeatureofJavaScriptthatmightcauseafewheadachestodevelopers,relatedtoloopsandscoping.Learnsometricksaboutloopsandscopingwithvarandlet

ThereisonefeatureofJavaScriptthatmightcauseafewheadachestodevelopers,relatedtoloopsandscoping.

Takethisexample:

constoperations=[]

for(vari=0;i<5;i++){

operations.push(()=>{

console.log(i)

})

}

for(constoperationofoperations){

operation()

}

Itbasicallyiteratesandfor5timesitaddsafunctiontoanarraycalledoperations.Thisfunctionsimplyconsolelogstheloopindexvariable i.

Lateritrunsthesefunctions.

Theexpectedresulthereshouldbe:

0

1

2

3

4

butactuallywhathappensisthis:

5

5

5

5

5

Whyisthisthecase?Becauseoftheuseof var.

Since vardeclarationsarehoisted,theabovecodeequalsto

LoopsandScope

131

Page 132: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

vari;

constoperations=[]

for(i=0;i<5;i++){

operations.push(()=>{

console.log(i)

})

}

for(constoperationofoperations){

operation()

}

so,inthefor-ofloop, iisstillvisible,it'sequalto5andeveryreferenceto iinthefunctionisgoingtousethisvalue.

Sohowshouldwedotomakethingsworkaswewant?

Thesimplestsolutionistouse letdeclarations.IntroducedinES2015,theyareagreathelpinavoidingsomeoftheweirdthingsabout vardeclarations.

Simplychanging varto letintheloopvariableisgoingtoworkfine:

constoperations=[]

for(leti=0;i<5;i++){

operations.push(()=>{

console.log(i)

})

}

for(constoperationofoperations){

operation()

}

Here'stheoutput:

0

1

2

3

4

Howisthispossible?Thisworksbecauseoneveryloopiteration iiscreatedasanewvariableeachtime,andeveryfunctionaddedtothe operationsarraygetsitsowncopyof i.

Keepinmindyoucannotuse constinthiscase,becausetherewouldbeanerroras fortriestoassignanewvalueintheseconditeration.

LoopsandScope

132

Page 133: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Anotherwaytosolvethisproblemwasverycommoninpre-ES6code,anditiscalledImmediatelyInvokedFunctionExpression(IIFE).

Inthiscaseyoucanwraptheentirefunctionandbind itoit.Sinceinthiswayyou'recreatingafunctionthatimmediatelyexecutes,youreturnanewfunctionfromit,sowecanexecuteitlater:

constoperations=[]

for(vari=0;i<5;i++){

operations.push(((j)=>{

return()=>console.log(j)

})(i))

}

for(constoperationofoperations){

operation()

}

LoopsandScope

133

Page 134: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TimersWhenwritingJavaScriptcode,youmightwanttodelaytheexecutionofafunction.LearnhowtousesetTimeoutandsetIntervaltoschedulefunctionsinthefuture

setTimeout()

WhenwritingJavaScriptcode,youmightwanttodelaytheexecutionofafunction.

Thisisthejobof setTimeout.Youspecifyacallbackfunctiontoexecutelater,andavalueexpressinghowlateryouwantittorun,inmilliseconds:

setTimeout(()=>{

//runsafter2seconds

},2000)

setTimeout(()=>{

//runsafter50milliseconds

},50)

Thissyntaxdefinesanewfunction.Youcancallwhateverotherfunctionyouwantinthere,oryoucanpassanexistingfunctionname,andasetofparameters:

constmyFunction=(firstParam,secondParam)=>{

//dosomething

}

//runsafter2seconds

setTimeout(myFunction,2000,firstParam,secondParam)

Timers

134

Page 135: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

setTimeoutreturnsthetimerid.Thisisgenerallynotused,butyoucanstorethisid,andclearitifyouwanttodeletethisscheduledfunctionexecution:

constid=setTimeout(()=>{

//shouldrunafter2seconds

},2000)

//Ichangedmymind

clearTimeout(id)

Zerodelay

Ifyouspecifythetimeoutdelayto 0,thecallbackfunctionwillbeexecutedassoonaspossible,butafterthecurrentfunctionexecution:

setTimeout(()=>{

console.log('after')

},0)

console.log('before')

willprint beforeafter.

ThisisespeciallyusefultoavoidblockingtheCPUonintensivetasksandletotherfunctionsbeexecutedwhileperformingaheavycalculation,byqueuingfunctionsinthescheduler.

Somebrowsers(IEandEdge)implementa setImmediate()methodthatdoesthissameexactfunctionality,butit'snotstandardandunavailableonotherbrowsers.Butit'sastandardfunctioninNode.js.

setInterval()

setIntervalisafunctionsimilarto setTimeout,withadifference:insteadofrunningthecallbackfunctiononce,itwillrunitforever,atthespecifictimeintervalyouspecify(inmilliseconds):

setInterval(()=>{

//runsevery2seconds

},2000)

Thefunctionaboverunsevery2secondsunlessyoutellittostop,using clearInterval,passingittheintervalidthat setIntervalreturned:

constid=setInterval(()=>{

Timers

135

Page 136: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

//runsevery2seconds

},2000)

clearInterval(id)

It'scommontocall clearIntervalinsidethesetIntervalcallbackfunction,toletitauto-determineifitshouldrunagainorstop.ForexamplethiscoderunssomethingunlessApp.somethingIWaithasthevalue arrived:

constinterval=setInterval(()=>{

if(App.somethingIWait==='arrived'){

clearInterval(interval)

return

}

//otherwisedothings

},100)

RecursivesetTimeoutsetIntervalstartsafunctioneverynmilliseconds,withoutanyconsiderationaboutwhenafunctionfinisheditsexecution.

Ifafunctiontakesalwaysthesameamountoftime,it'sallfine:

Maybethefunctiontakesdifferentexecutiontimes,dependingonnetworkconditionsforexample:

Andmaybeonelongexecutionoverlapsthenextone:

Toavoidthis,youcanschedulearecursivesetTimeouttobecalledwhenthecallbackfunctionfinishes:

Timers

136

Page 137: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

constmyFunction=()=>{

//dosomething

setTimeout(myFunction,1000)

}

setTimeout(

myFunction()

},1000)

toachievethisscenario:

setTimeoutand setIntervalareavailableinNode.js,throughtheTimersmodule.

Node.jsalsoprovides setImmediate(),whichisequivalenttousing setTimeout(()=>{},0),mostlyusedtoworkwiththeNode.jsEventLoop.

Timers

137

Page 138: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

this`this`isavaluethathasdifferentvaluesdependingonwhereit'sused.NotknowingthistinydetailofJavaScriptcancausealotofheadaches,soit'sworthtaking5minutestolearnallthetricks

thisisavaluethathasdifferentvaluesdependingonwhereit'sused.

NotknowingthistinydetailofJavaScriptcancausealotofheadaches,soit'sworthtaking5minutestolearnallthetricks.

thisinstrictmodeOutsideanyobject, thisinstrictmodeisalways undefined.

NoticeImentionedstrictmode.Ifstrictmodeisdisabled(thedefaultstateifyoudon'texplicitlyadd 'usestrict'ontopofyourfile),youareintheso-calledsloppymode,and this-unlesssomespecificcasesmentionedherebelow-hasthevalueoftheglobalobject.

Whichmeans windowinabrowsercontext.

thisinmethodsAmethodisafunctionattachedtoanobject.

Youcanseeitinvariousforms.

this

138

Page 139: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Here'sone:

constcar={

maker:'Ford',

model:'Fiesta',

drive(){

console.log(`Drivinga${this.maker}${this.model}car!`)

}

}

car.drive()

//DrivingaFordFiestacar!

Inthiscase,usingaregularfunction, thisisautomaticallyboundtotheobject.

Note:theabovemethoddeclarationisthesameas drive:function(){...,butshorter:

constcar={

maker:'Ford',

model:'Fiesta',

drive:function(){

console.log(`Drivinga${this.maker}${this.model}car!`)

}

}

Thesameworksinthisexample:

constcar={

maker:'Ford',

model:'Fiesta'

}

car.drive=function(){

console.log(`Drivinga${this.maker}${this.model}car!`)

}

car.drive()

//DrivingaFordFiestacar!

Anarrowfunctiondoesnotworkinthesameway,asit'slexicallybound:

constcar={

maker:'Ford',

model:'Fiesta',

drive:()=>{

console.log(`Drivinga${this.maker}${this.model}car!`)

}

}

this

139

Page 140: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

car.drive()

//Drivingaundefinedundefinedcar!

BindingarrowfunctionsYoucannotbindavaluetoanarrowfunction,likeyoudowithnormalfunctions.

It'ssimplynotpossibleduetothewaytheywork. thisislexicallybound,whichmeansitsvalueisderivedfromthecontextwheretheyaredefined.

Explicitlypassanobjecttobeusedas thisJavaScriptoffersafewwaystomap thistoanyobjectyouwant.

Using bind(),atthefunctiondeclarationstep:

constcar={

maker:'Ford',

model:'Fiesta'

}

constdrive=function(){

console.log(`Drivinga${this.maker}${this.model}car!`)

}.bind(car)

drive()

//DrivingaFordFiestacar!

Youcouldalsobindanexistingobjectmethodtoremapits thisvalue:

constcar={

maker:'Ford',

model:'Fiesta',

drive(){

console.log(`Drivinga${this.maker}${this.model}car!`)

}

}

constanotherCar={

maker:'Audi',

model:'A4'

}

car.drive.bind(anotherCar)()

//DrivingaAudiA4car!

this

140

Page 141: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Using call()or apply(),atthefunctioninvocationstep:

constcar={

maker:'Ford',

model:'Fiesta'

}

constdrive=function(kmh){

console.log(`Drivinga${this.maker}${this.model}carat${kmh}km/h!`)

}

drive.call(car,100)

//DrivingaFordFiestacarat100km/h!

drive.apply(car,[100])

//DrivingaFordFiestacarat100km/h!

Thefirstparameteryoupassto call()or apply()isalwaysboundto this.Thedifferencebetweencall()andapply()isjustthatthesecondonewantsanarrayastheargumentslist,whilethefirstacceptsavariablenumberofparameters,whichpassesasfunctionarguments.

ThespecialcaseofbrowsereventhandlersIneventhandlerscallbacks, thisreferstotheHTMLelementthatreceivedtheevent:

document.querySelector('#button').addEventListener('click',function(e){

console.log(this)//HTMLElement

}

Youcanbinditusing

document.querySelector('#button').addEventListener(

'click',

function(e){

console.log(this)//Windowifglobal,oryourcontext

}.bind(this)

)

this

141

Page 142: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

StrictModeStrictModeisanES5feature,andit'sawaytomakeJavaScriptbehaveinabetterway.Andinadifferentway,asenablingStrictModechangesthesemanticsoftheJavaScriptlanguage.It'sreallyimportanttoknowthemaindifferencesbetweenJavaScriptcodeinstrictmode,andnormalJavaScript,whichisoftenreferredassloppymode

StrictModeisanES5feature,andit'sawaytomakeJavaScriptbehaveinabetterway.

Andinadifferentway,asenablingStrictModechangesthesemanticsoftheJavaScriptlanguage.

It'sreallyimportanttoknowthemaindifferencesbetweenJavaScriptcodeinstrictmode,and"normal"JavaScript,whichisoftenreferredassloppymode.

StrictModemostlyremovesfunctionalitythatwaspossibleinES3,anddeprecatedsinceES5(butnotremovedbecauseofbackwardscompatibilityrequirements)

HowtoenableStrictMode

StrictMode

142

Page 143: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Strictmodeisoptional.AswitheverybreakingchangeinJavaScript,wecan'tsimplychangehowthelanguagebehavesbydefault,becausethatwouldbreakgazillionsofJavaScriptaround,andJavaScriptputsalotofeffortintomakingsure1996JavaScriptcodestillworkstoday.It'sakeyofitssuccess.

Sowehavethe 'usestrict'directiveweneedtousetoenableStrictMode.

Youcanputitatthebeginningofafile,toapplyittoallthecodecontainedinthefile:

'usestrict'

constname='Flavio'

consthello=()=>'hey'

//...

YoucanalsoenableStrictModeforanindividualfunction,byputting 'usestrict'atthebeginningofthefunctionbody:

functionhello(){

'usestrict'

return'hey'

}

Thisisusefulwhenoperatingonlegacycode,whereyoudon'thavethetimetotestortheconfidencetoenablestrictmodeonthewholefile.

WhatchangesinStrictMode

Accidentalglobalvariables

Ifyouassignavaluetoanundeclaredvariable,JavaScriptbydefaultcreatesthatvariableontheglobalobject:

;(function(){

variable='hey'

})()(()=>{

name='Flavio'

})()

variable//'hey'

name//'Flavio'

TurningonStrictMode,anerrorisraisedifyoutrytodowhatwedidabove:

StrictMode

143

Page 144: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

;(function(){

'usestrict'

variable='hey'

})()(()=>{

'usestrict'

myname='Flavio'

})()

Assignmenterrors

JavaScriptsilentlyfailssomeconversionerrors.

InStrictMode,thosesilenterrorsnowraiseissues:

constundefined=1(()=>{

'usestrict'

undefined=1

})()

StrictMode

144

Page 145: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ThesameappliestoInfinity,NaN, eval, argumentsandmore.

InJavaScriptyoucandefineapropertyofanobjecttobenotwritable,byusing

constcar={}

Object.defineProperty(car,'color',{value:'blue',writable:false})

Instrictmode,youcan'toverridethisvalue,whileinsloppymodethat'spossible:

Thesameworksforgetters:

constcar={

getcolor(){

return'blue'

}

}

car.color='red'(

//ok

()=>{

'usestrict'

StrictMode

145

Page 146: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

car.color='yellow'//TypeError:Cannotsetpropertycolorof#<Object>whichhasonl

yagetter

}

)()

Sloppymodeallowstoextendanon-extensibleobject:

constcar={color:'blue'}

Object.preventExtensions(car)

car.model='Fiesta'(

//ok

()=>{

'usestrict'

car.owner='Flavio'//TypeError:Cannotaddpropertyowner,objectisnotextensible

}

)()

Also,sloppymodeallowstosetpropertiesonprimitivevalues,withoutfailing,butalsowithoutdoingnothingatall:

true.false=''(

//''

1

).name=

'xxx'//'xxx'

vartest='test'//undefined

test.testing=true//true

test.testing//undefined

Strictmodefailsinallthosecases:

;(()=>{

'usestrict'

true.false=''(

//TypeError:Cannotcreateproperty'false'onboolean'true'

1

).name=

'xxx'//TypeError:Cannotcreateproperty'name'onnumber'1'

'test'.testing=true//TypeError:Cannotcreateproperty'testing'onstring'test'

})()

Deletionerrors

Insloppymode,ifyoutrytodeleteapropertythatyoucannotdelete,JavaScriptsimplyreturnsfalse,whileinStrictMode,itraisesaTypeError:

deleteObject.prototype(

StrictMode

146

Page 147: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

//false

()=>{

'usestrict'

deleteObject.prototype//TypeError:Cannotdeleteproperty'prototype'offunctionOb

ject(){[nativecode]}

}

)()

Functionargumentswiththesamename

Innormalfunctions,youcanhaveduplicateparameternames:

(function(a,a,b){

console.log(a,b)

})(1,2,3)

//23

(function(a,a,b){

'usestrict'

console.log(a,b)

})(1,2,3)

//UncaughtSyntaxError:Duplicateparameternamenotallowedinthiscontext

Notethatarrowfunctionsalwaysraisea SyntaxErrorinthiscase:

((a,a,b)=>{

console.log(a,b)

})(1,2,3)

//UncaughtSyntaxError:Duplicateparameternamenotallowedinthiscontext

Octalsyntax

OctalsyntaxinStrictModeisdisabled.Bydefault,prependinga 0toanumbercompatiblewiththeoctalnumericformatmakesit(sometimesconfusingly)interpretedasanoctalnumber:

(()=>{

console.log(010)

})()

//8

(()=>{

'usestrict'

console.log(010)

})()

//UncaughtSyntaxError:Octalliteralsarenotallowedinstrictmode.

StrictMode

147

Page 148: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

YoucanstillenableoctalnumbersinStrictModeusingthe 0oXXsyntax:

;(()=>{

'usestrict'

console.log(0o10)

})()

//8

Removed with

StrictModedisablesthe withkeyword,toremovesomeedgecasesandallowmoreoptimizationatthecompilerlevel.

StrictMode

148

Page 149: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Immediately-invokedFunctionExpressions(IIFE)AnImmediately-invokedFunctionExpressionisawaytoexecutefunctionsimmediately,assoonastheyarecreated.IIFEsareveryusefulbecausetheydon'tpollutetheglobalobject,andtheyareasimplewaytoisolatevariablesdeclarations

AnImmediately-invokedFunctionExpression(IIFEforfriends)isawaytoexecutefunctionsimmediately,assoonastheyarecreated.

IIFEsareveryusefulbecausetheydon'tpollutetheglobalobject,andtheyareasimplewaytoisolatevariablesdeclarations.

ThisisthesyntaxthatdefinesanIIFE:

;(function(){

/**/

})()

IIFEscanbedefinedwitharrowfunctionsaswell:

Immediately-invokedFunctionExpressions(IIFE)

149

Page 150: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

;(()=>{

/**/

})()

Webasicallyhaveafunctiondefinedinsideparentheses,andthenweappend ()toexecutethatfunction: (https://flaviocopes.com/*function*/)().

Thosewrappingparenthesesareactuallywhatmakeourfunction,internally,beconsideredanexpression.Otherwise,thefunctiondeclarationwouldbeinvalid,becausewedidn'tspecifyanyname:

Functiondeclarationswantaname,whilefunctionexpressionsdonotrequireit.

Youcouldalsoputtheinvokingparenthesesinsidetheexpressionparentheses,thereisnodifference,justastylingpreference:

(function(){

/**/

}())

(()=>{

/**/

}())

AlternativesyntaxusingunaryoperatorsThereissomeweirdersyntaxthatyoucanusetocreateanIIFE,butit'sveryrarelyusedintherealworld,anditreliesonusinganyunaryoperator:

;-(function(){

/**/

})()+

(function(){

/**/

})()

Immediately-invokedFunctionExpressions(IIFE)

150

Page 151: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

~(function(){

/**/

})()

!(function(){

/**/

})()

(doesnotworkwitharrowfunctions)

NamedIIFEAnIIFEcanalsobenamedregularfunctions(notarrowfunctions).Thisdoesnotchangethefactthatthefunctiondoesnot"leak"totheglobalscope,anditcannotbeinvokedagainafteritsexecution:

;(functiondoSomething(){

/**/

})()

IIFEsstartingwithasemicolonYoumightseethisinthewild:

;(function(){

/**/

})()

ThispreventsissueswhenblindlyconcatenatingtwoJavaScriptfiles.SinceJavaScriptdoesnotrequiresemicolons,youmightconcatenatewithafilewithsomestatementsinitslastlinethatcausesasyntaxerror.

Thisproblemisessentiallysolvedwith"smart"codebundlerslikewebpack.

Immediately-invokedFunctionExpressions(IIFE)

151

Page 152: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

MathoperatorsPerformingmathoperationsandcalculusisaverycommonthingtodowithanyprogramminglanguage.JavaScriptoffersseveraloperatorstohelpusworkwithnumbers

Performingmathoperationsandcalculusisaverycommonthingtodowithanyprogramminglanguage.

JavaScriptoffersseveraloperatorstohelpusworkwithnumbers.

Operators

Arithmeticoperators

Addition(+)

constthree=1+2

constfour=three+1

The +operatoralsoservesasstringconcatenationifyouusestrings,sopayattention:

constthree=1+2

three+1//4

'three'+1//three1

Subtraction(-)

consttwo=4-2

Division(https://flaviocopes.com/)

Returnsthequotientofthefirstoperatorandthesecond:

constresult=20/5//result===4

constresult=20/7//result===2.857142857142857

Ifyoudividebyzero,JavaScriptdoesnotraiseanyerrorbutreturnsthe Infinityvalue(or -Infinityifthevalueisnegative).

Mathoperators

152

Page 153: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

1/0//Infinity

-1/0//-Infinity

Remainder(%)

Theremainderisaveryusefulcalculationinmanyusecases:

constresult=20%5//result===0

constresult=20%7//result===6

Areminderbyzeroisalways NaN,aspecialvaluethatmeans"NotaNumber":

1%0//NaN

-1%0//NaN

Multiplication(*)

1*2//2

-1*2//-2

Exponentiation(**)

Raisethefirstoperandtothepowersecondoperand

1**2//1

2**1//2

2**2//4

2**8//256

8**2//64

Unaryoperators

Increment(++)

Incrementanumber.Thisisaunaryoperator,andifputbeforethenumber,itreturnsthevalueincremented.

Ifputafterthenumber,itreturnstheoriginalvalue,thenincrementsit.

letx=0

x++//0

x//1

++x//2

Mathoperators

153

Page 154: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Decrement(--)

Worksliketheincrementoperator,exceptitdecrementsthevalue.

letx=0

x--//0

x//-1

--x//-2

Unarynegation(-)

Returnthenegationoftheoperand

letx=2

-x//-2

x//2

Unaryplus(+)

Iftheoperandisnotanumber,ittriestoconvertit.Otherwiseiftheoperandisalreadyanumber,itdoesnothing.

letx=2

+x//2

x='2'

+x//2

x='2a'

+x//NaN

AssignmentshortcutsTheregularassignmentoperator, =,hasseveralshortcutsforallthearithmeticoperatorswhichletyoucombineassignment,assigningtothefirstoperandtheresultoftheoperationswiththesecondoperand.

Theyare:

+=:additionassignment-=:subtractionassignment*=:multiplicationassignment

Mathoperators

154

Page 155: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

/=:divisionassignment%=:remainderassignment**=:exponentiationassignment

Examples:

consta=0

a+=5//a===5

a-=2//a===3

a*=2//a===6

a/=2//a===3

a%=2//a===1

PrecedencerulesEverycomplexstatementwillintroduceprecedenceproblems.

Takethis:

consta=1*2+5/2%2

Theresultis2.5,butwhy?Whatoperationsareexecutedfirst,andwhichneedtowait?

Someoperationshavemoreprecedencethantheothers.Theprecedencerulesarelistedinthistable:

Operator Description

- + ++ -- unaryoperators,incrementanddecrement

* / % multiply/divide

+ - addition/subtraction

= += -= *= /= %= **= assignments

Operationsonthesamelevel(like +and -)areexecutedintheordertheyarefound

Followingthistable,wecansolvethiscalculation:

consta=1*2+5/2%2

consta=1*2+5/2%2

consta=2+2.5%2

consta=2+0.5

consta=2.5

Mathoperators

155

Page 156: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Mathoperators

156

Page 157: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

TheMathobjectTheMathobjectcontainslotsofutilitiesmath-related.Thistutorialdescribesthemall

TheMathobjectcontainslotsofutilitiesmath-related.

Itcontainsconstantsandfunctions.

Constants

Item Description

Math.E Theconstante,baseofthenaturallogarithm(means~2.71828)

Math.LN10 Theconstantthatrepresentsthebasee(natural)logarithmof10

Math.LN2 Theconstantthatrepresentsthebasee(natural)logarithmof2

Math.LOG10E Theconstantthatrepresentsthebase10logarithmofe

Math.LOG2E Theconstantthatrepresentsthebase2logarithmofe

Math.PI Theπconstant(~3.14159)

Math.SQRT1_2 Theconstantthatrepresentsthereciprocalofthesquarerootof2

Math.SQRT2 Theconstantthatrepresentsthesquarerootof2

FunctionsAllthosefunctionsarestatic.Mathcannotbeinstantiated.

Math.abs()

Returnstheabsolutevalueofanumber

Math.abs(2.5)//2.5

Math.abs(-2.5)//2.5

Math.acos()

Returnsthearccosineoftheoperand

Theoperandmustbebetween-1and1

TheMathobject

157

Page 158: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Math.acos(0.8)//0.6435011087932843

Math.asin()

Returnsthearcsineoftheoperand

Theoperandmustbebetween-1and1

Math.asin(0.8)//0.9272952180016123

Math.atan()

Returnsthearctangentoftheoperand

Math.atan(30)//1.5374753309166493

Math.atan2()

Returnsthearctangentofthequotientofitsarguments.

Math.atan2(30,20)//0.982793723247329

Math.ceil()

Roundsanumberup

Math.ceil(2.5)//3

Math.ceil(2)//2

Math.ceil(2.1)//3

Math.ceil(2.99999)//3

Math.cos()

Returnthecosineofanangleexpressedinradiants

Math.cos(0)//1

Math.cos(Math.PI)//-1

Math.exp()

ReturnthevalueofMath.Emultipliedpertheexponentthat'spassedasargument

TheMathobject

158

Page 159: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Math.exp(1)//2.718281828459045

Math.exp(2)//7.38905609893065

Math.exp(5)//148.4131591025766

Math.floor()

Roundsanumberdown

Math.ceil(2.5)//2

Math.ceil(2)//2

Math.ceil(2.1)//2

Math.ceil(2.99999)//2

Math.log()

Returnthebasee(natural)logarithmofanumber

Math.log(10)//2.302585092994046

Math.log(Math.E)//1

Math.max()

Returnthehighestnumberinthesetofnumberspassed

Math.max(1,2,3,4,5)//5

Math.max(1)//1

Math.min()

Returnthesmallestnumberinthesetofnumberspassed

Math.max(1,2,3,4,5)//1

Math.max(1)//1

Math.pow()

Returnthefirstargumentraisedtothesecondargument

Math.pow(1,2)//1

Math.pow(2,1)//2

Math.pow(2,2)//4

Math.pow(2,4)//16

TheMathobject

159

Page 160: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Math.random()

Returnsapseudorandomnumberbetween0.0and1.0

Math.random()//0.9318168241227056

Math.random()//0.35268950194094395

Math.round()

Roundsanumbertothenearestinteger

Math.round(1.2)//1

Math.round(1.6)//2

Math.sin()

Calculatesthesinofanangleexpressedinradiants

Math.sin(0)//0

Math.sin(Math.PI)//1.2246467991473532e-16)

Math.sqrt()

Returnthesquarerootoftheargument

Math.sqrt(4)//2

Math.sqrt(16)//4

Math.sqrt(5)//2.23606797749979

Math.tan()

Calculatesthetangentofanangleexpressedinradiants

Math.tan(0)//0

Math.tan(Math.PI)//-1.2246467991473532e-16

TheMathobject

160

Page 161: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ESModulesESModulesistheECMAScriptstandardforworkingwithmodules.WhileNode.jshasbeenusingtheCommonJSstandardsinceyears,thebrowserneverhadamodulesystem,aseverymajordecisionsuchasamodulesystemmustbefirststandardizedbyECMAScriptandthenimplemented

IntroductiontoESModulesESModulesistheECMAScriptstandardforworkingwithmodules.

WhileNode.jshasbeenusingtheCommonJSstandardsinceyears,thebrowserneverhadamodulesystem,aseverymajordecisionsuchasamodulesystemmustbefirststandardizedbyECMAScriptandthenimplementedbythebrowser.

ThisstandardizationprocesscompletedwithES6andbrowsersstartedimplementingthisstandardtryingtokeepeverythingwellaligned,workingallinthesameway,andnowESModulesaresupportedinChrome,Safari,EdgeandFirefox(sinceversion60).

ESModules

161

Page 162: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Modulesareverycool,becausetheyletyouencapsulateallsortsoffunctionality,andexposethisfunctionalitytootherJavaScriptfiles,aslibraries.

TheESModulesSyntaxThesyntaxtoimportamoduleis:

importpackagefrom'module-name'

whileCommonJSuses

constpackage=require('module-name')

AmoduleisaJavaScriptfilethatexportsoneormorevalue(objects,functionsorvariables),usingthe exportkeyword.Forexample,thismoduleexportsafunctionthatreturnsastringuppercase:

uppercase.js

exportdefaultstr=>str.toUpperCase()

ESModules

162

Page 163: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Inthisexample,themoduledefinesasingle,defaultexport,soitcanbeananonymousfunction.Otherwiseitwouldneedanametodistinguishitfromotherexports.

Now,anyotherJavaScriptmodulecanimportthefunctionalityofferedbyuppercase.jsbyimportingit.

AnHTMLpagecanaddamodulebyusinga <script>tagwiththespecial type="module"attribute:

<scripttype="module"src="index.js"></script>

Note:thismoduleimportbehaveslikea deferscriptload.SeeefficientlyloadJavaScriptwithdeferandasync

It'simportanttonotethatanyscriptloadedwith type="module"isloadedinstrictmode.

Inthisexample,the uppercase.jsmoduledefinesadefaultexport,sowhenweimportit,wecanassignitanameweprefer:

importtoUpperCasefrom'./uppercase.js'

andwecanuseit:

toUpperCase('test')//'TEST'

Youcanalsouseanabsolutepathforthemoduleimport,toreferencemodulesdefinedonanotherdomain:

importtoUpperCasefrom'https://flavio-es-modules-example.glitch.me/uppercase.js'

Thisisalsovalidimportsyntax:

import{foo}from'/uppercase.js'

import{foo}from'../uppercase.js'

Thisisnot:

import{foo}from'uppercase.js'

import{foo}from'utils/uppercase.js'

It'seitherabsolute,orhasa ./or /beforethename.

ESModules

163

Page 164: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

Otherimport/exportoptionsWesawthisexampleabove:

exportdefaultstr=>str.toUpperCase()

Thiscreatesonedefaultexport.Inafilehoweveryoucanexportmorethanonething,byusingthissyntax:

consta=1

constb=2

constc=3

export{a,b,c}

Anothermodulecanimportallthoseexportsusing

import*from'module'

Youcanimportjustafewofthoseexports,usingthedestructuringassignment:

import{a}from'module'

import{a,b}from'module'

Youcanrenameanyimport,forconvenience,using as:

import{a,bastwo}from'module'

Youcanimportthedefaultexport,andanynon-defaultexportbyname,likeinthiscommonReactimport:

importReact,{Component}from'react'

YoucancheckanESModulesexampleonhttps://glitch.com/edit/#!/flavio-es-modules-example?path=index.html

CORS

ESModules

164

Page 165: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ModulesarefetchedusingCORS.Thismeansthatifyoureferencescriptsfromotherdomains,theymusthaveavalidCORSheaderthatallowscross-siteloading(like Access-Control-Allow-Origin:*)

Whataboutbrowsersthatdonotsupportmodules?Useacombinationof type="module"and nomodule:

<scripttype="module"src="module.js"></script>

<scriptnomodulesrc="fallback.js"></script>

ConclusionESModulesareoneofthebiggestfeaturesintroducedinmodernbrowsers.TheyarepartofES6buttheroadtoimplementthemhasbeenlong.

Wecannowusethem!Butwemustalsorememberthathavingmorethanafewmodulesisgoingtohaveaperformancehitonourpages,asit'sonemorestepthatthebrowsermustperformatruntime.

WebpackisprobablygoingtostillbeahugeplayerevenifESModuleslandinthebrowser,buthavingsuchafeaturedirectlybuiltinthelanguageishugeforaunificationofhowmodulesworkintheclient-sideandonNode.jsaswell.

ESModules

165

Page 166: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

CommonJSTheCommonJSmodulespecificationisthestandardusedinNode.jsforworkingwithmodules.Modulesareverycool,becausetheyletyouencapsulateallsortsoffunctionality,andexposethisfunctionalitytootherJavaScriptfiles,aslibraries

TheCommonJSmodulespecificationisthestandardusedinNode.jsforworkingwithmodules.

Client-sideJavaScriptthatrunsinthebrowserusesanotherstandard,calledESModules

Modulesareverycool,becausetheyletyouencapsulateallsortsoffunctionality,andexposethisfunctionalitytootherJavaScriptfiles,aslibraries.Theyletyoucreateclearlyseparateandreusablesnippetsoffunctionality,eachtestableonitsown.

ThehugenpmecosystemisbuiltuponthisCommonJSformat.

Thesyntaxtoimportamoduleis:

constpackage=require('module-name')

CommonJS

166

Page 167: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

InCommonJS,modulesareloadedsynchronously,andprocessedintheordertheJavaScriptruntimefindsthem.Thissystemwasbornwithserver-sideJavaScriptinmind,andisnotsuitablefortheclient-side(thisiswhyESModuleswereintroduced).

AJavaScriptfileisamodulewhenitexportsoneormoreofthesymbolsitdefines,beingthemvariables,functions,objects:

uppercase.js

exports.uppercase=str=>str.toUpperCase()

AnyJavaScriptfilecanimportandusethismodule:

constuppercaseModule=require('uppercase.js')

uppercaseModule.uppercase('test')

AsimpleexamplecanbefoundinthisGlitch.

Youcanexportmorethanonevalue:

exports.a=1

exports.b=2

exports.c=3

andimportthemindividuallyusingthedestructuringassignment:

const{a,b,c}=require('./uppercase.js')

orjustexportonevalueusing:

//file.js

module.exports=value

andimportitusing

constvalue=require('./file.js')

CommonJS

167

Page 168: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

GlossaryAguidetoafewtermsusedinfrontenddevelopmentthatmightbealientoyou

AsynchronousCodeisasynchronouswhenyouinitiatesomething,forgetaboutit,andwhentheresultisreadyyougetitbackwithouthavingtowaitforit.ThetypicalexampleisanAJAXcall,whichmighttakeevensecondsandinthemeantimeyoucompleteotherstuff,andwhentheresponseisready,thecallbackfunctiongetscalled.Promisesandasync/awaitarethemodernwaytohandleasync.

BlockInJavaScriptablockisdelimitedcurlybraces( {}).An ifstatementcontainsablock,aforloopcontainsablock.

BlockScopingWithFunctionScoping,anyvariabledefinedinablockisvisibleandaccessiblefrominsidethewholeblock,butnotoutsideofit.

CallbackAcallbackisafunctionthat'sinvokedwhensomethinghappens.Aclickeventassociatedtoanelementhasacallbackfunctionthat'sinvokedwhentheuserclickstheelement.Afetchrequesthasacallbackthat'scalledwhentheresourceisdownloaded.

DeclarativeAdeclarativeapproachiswhenyoutellthemachinewhatyouneedtodo,andyouletitfigureoutthedetails.Reactisconsidereddeclarative,asyoureasonaboutabstractionsratherthaneditingtheDOMdirectly.Everyhighlevelprogramminglanguageismoredeclarativethana

Glossary

168

Page 169: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

lowlevelprogramminglanguagelikeAssembler.JavaScriptismoredeclarativethanC.HTMLisdeclarative.

FallbackAfallbackisusedtoprovideagoodexperiencewhenauserhasn'taccesstoaparticularfunctionality.ForexampleauserthatbrowseswithJavaScriptdisabledshouldbeabletohaveafallbacktoaplainHTMLversionofthepage.OrforabrowserthathasnotimplementedanAPI,youshouldhaveafallbacktoavoidcompletelybreakingtheexperienceoftheuser.

FunctionScopingWithFunctionScoping,anyvariabledefinedinafunctionisvisibleandaccessiblefrominsidethewholefunction.

ImmutabilityAvariableisimmutablewhenitsvaluecannotchangeafterit'screated.Amutablevariablecanbechanged.Thesameappliestoobjectsandarrays.

LexicalScopingLexicalScopingisaparticularkindofscopingwherevariablesofaparentfunctionaremadeavailabletoinnerfunctionsaswell.Thescopeofaninnerfunctionalsoincludesthescopeofaparentfunction.

PolyfillApolyfillisawaytoprovidenewfunctionalityavailableinmodernJavaScriptoramodernbrowserAPItoolderbrowsers.Apolyfillisaparticularkindofshim.

PurefunctionAfunctionthathasnosideeffects(doesnotmodifyexternalresources),anditsoutputisonlydeterminedbythearguments.Youcouldcallthisfunction1Mtimes,andgiventhesamesetofarguments,theoutputwillalwaysbethesame.

Glossary

169

Page 170: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

ReassignmentJavaScriptwith varand letdeclarationallowsyoutoreassignavariableindefinitely.Withconstdeclarationsyoueffectivelydeclareanimmutablevalueforstrings,integers,booleans,andanobjectthatcannotbereassigned(butyoucanstillmodifyitthroughitsmethods).

ScopeScopeisthesetofvariablesthat'svisibletoapartoftheprogram.

ScopingScopingisthesetofrulesthat'sdefinedinaprogramminglanguagetodeterminethevalueofavariable.

ShimAshimisalittlewrapperaroundafunctionality,orAPI.It'sgenerallyusedtoabstractsomething,pre-fillparametersoraddapolyfillforbrowsersthatdonotsupportsomefunctionality.Youcanconsideritlikeacompatibilitylayer.

SideeffectAsideeffectiswhenafunctioninteractswithsomeotherfunctionorobjectoutsideit.Interactionwiththenetworkorthefilesystem,orwiththeUI,areallsideeffects.

StateStateusuallycomesintoplaywhentalkingaboutComponents.Acomponentcanbestatefulifitmanagesitsowndata,orstatelessifitdoesn't.

StatefulAstatefulcomponent,functionorclassmanagesitsownstate(data).Itcouldstoreanarray,acounteroranythingelse.

Glossary

170

Page 171: Table of Contentsedu-9.de/uploads/books/javascript-handbook.pdf · JavaScript is now also the language powering databases and many more applications, and it's even possible to develop

StatelessAstatelesscomponent,functionorclassisalsocalleddumbbecauseit'sincapableofhavingitsowndatatomakedecisions,soitsoutputorpresentationisentirelybasedonitsarguments.Thisimpliesthatpurefunctionsarestateless.

StrictmodeStrictmodeisanECMAScript5.1newfeature,whichcausestheJavaScriptruntimetocatchmoreerrors,butithelpsyouimprovetheJavaScriptcodebydenyingundeclaredvariablesandotherthingsthatmightcauseoverlookedissueslikeduplicatedobjectpropertiesandothersubtlethings.Hint:useit.Thealternativeis"sloppymode"whichisnotagoodthingevenlookingatthenamewegaveit.

TreeShakingTreeshakingmeansremoving"deadcode"fromthebundleyoushiptoyourusers.Ifyouaddsomecodethatyouneveruseinyourimportstatements,that'snotgoingtobesenttotheusersofyourapp,toreducefilesizeandloadingtime.

Glossary

171