table of contents · checking (something that typescript and flow aim to improve) interpreted:...
TRANSCRIPT
![Page 1: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/1.jpg)
![Page 2: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/2.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/3.jpg)
this
StrictMode
Immediately-invokedFunctionExpressions(IIFE)
Mathoperators
TheMathobject
ESModules
CommonJS
Glossary
3
![Page 4: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/4.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/5.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/6.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/7.jpg)
Currently,thelatestapprovedJavaScriptversionisES2017.
IntroductiontoJavaScript
7
![Page 8: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/8.jpg)
ECMAScriptECMAScriptisthestandarduponwhichJavaScriptisbased,andit'softenabbreviatedtoES.DiscovereverythingaboutECMAScript,andthelastfeaturesaddedinES6,7,8
WheneveryoureadaboutJavaScriptyou'llinevitablyseeoneoftheseterms:
ES3ES5ES6ES7ES8ES2015ES2016ES2017ECMAScript2017ECMAScript2016
ECMAScript
8
![Page 9: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/9.jpg)
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.
CurrentECMAScriptversionThecurrentECMAScriptversionisES2017,AKAES8
ItwasreleasedinJune2017.
Whenisthenextversioncomingout?HistoricallyJavaScripteditionshavebeenstandardizedduringthesummer,sowecanexpectECMAScript2019(namedES2019orES10)tobereleasedinsummer2019,butthisisjustspeculation.
ECMAScript
9
![Page 10: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/10.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/11.jpg)
ES.NextisanamethatalwaysindicatesthenextversionofJavaScript.
Soatthetimeofwriting,ES9hasbeenreleased,andES.NextisES10
ECMAScript
11
![Page 12: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/12.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/13.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/14.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/15.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/16.jpg)
{
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/17.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/18.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/19.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/20.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/21.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/22.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/23.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/24.jpg)
The **operatorisstandardizedacrossmanylanguagesincludingPython,Ruby,MATLAB,Lua,Perlandmanyothers.
ES2016
24
![Page 25: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/25.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/26.jpg)
'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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/27.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/28.jpg)
;('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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/29.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/30.jpg)
SharedMemoryandAtomicsWebWorkersareusedtocreatemultithreadedprogramsinthebrowser.
Theyofferamessagingprotocolviaevents.SinceES2017,youcancreateasharedmemoryarraybetweenwebworkersandtheircreator,usinga SharedArrayBuffer.
Sinceit'sunknownhowmuchtimewritingtoasharedmemoryportiontakestopropagate,Atomicsareawaytoenforcethatwhenreadingavalue,anykindofwritingoperationiscompleted.
Anymoredetailonthiscanbefoundinthespecproposal,whichhassincebeenimplemented.
ES2017
30
![Page 31: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/31.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/32.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/33.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/34.jpg)
/^\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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/35.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/36.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/37.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/38.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/39.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/40.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/41.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/42.jpg)
LexicalStructure
42
![Page 43: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/43.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/44.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/45.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/46.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/47.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/48.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/49.jpg)
Functions,arraysandwhatwecallobjectsareobjecttypes.Theyarespecialontheirown,buttheyinheritmanypropertiesofobjects,likehavingpropertiesandalsohavingmethodsthatcanactonthoseproperties.
Types
49
![Page 50: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/50.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/51.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/52.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/53.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/54.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/55.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/56.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/57.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/58.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/59.jpg)
Classes
59
![Page 60: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/60.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/61.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/62.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/63.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/64.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/65.jpg)
Semicolons
65
![Page 66: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/66.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/67.jpg)
on${1+1}lines`
ThosearecalledTemplateLiterals.
Quotes
67
![Page 68: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/68.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/69.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/70.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/71.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/72.jpg)
for(const[i,val]ofexpressions){
string+=literals[i]+val
}
string+=literals[literals.length-1]
returnstring
}
TemplateLiterals
72
![Page 73: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/73.jpg)
FunctionsLearnallaboutfunctions,fromthegeneraloverviewtothetinydetailsthatwillimprovehowyouusethem
IntroductionEverythinginJavaScripthappensinfunctions.
Afunctionisablockofcode,selfcontained,thatcanbedefinedonceandrunanytimesyouwant.
Afunctioncanoptionallyacceptparameters,andreturnsonevalue.
FunctionsinJavaScriptareobjects,aspecialkindofobjects:functionobjects.Theirsuperpowerliesinthefactthattheycanbeinvoked.
Inaddition,functionsaresaidtobefirstclassfunctionsbecausetheycanbeassignedtoavalue,andtheycanbepassedasargumentsandusedasareturnvalue.
Syntax
Functions
73
![Page 74: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/74.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/75.jpg)
}
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/76.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/77.jpg)
Usingobjects:
NestedfunctionsFunctionscanbedefinedinsideotherfunctions:
constdosomething=()=>{
constdosomethingelse=()=>{}
dosomethingelse()
return'test'
}
Functions
77
![Page 78: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/78.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/79.jpg)
Thisisbecausethehandlingof thisisdifferentinthetwofunctionsdeclarationsstyle. thisinthearrowfunctionreferstotheenclosingfunctioncontext,whichinthiscaseisthe windowobject:
this,whichreferstothehostobjectusing function()
Functions
79
![Page 80: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/80.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/81.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/82.jpg)
Thisisbecause vardeclarationsarehoistedandinitializedwith undefinedasavalue,whileconstand letarehoistedbutnotinitialized.
Functions
82
![Page 83: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/83.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/84.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/85.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/86.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/87.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/88.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/89.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/90.jpg)
},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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/91.jpg)
}
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/92.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/93.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/94.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/95.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/96.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/97.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/98.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/99.jpg)
Noticetheuseof const.Thisloopcreatesanewscopeineveryiteration,sowecansafelyusethatinsteadof let.
for...invs for...ofThedifferencewith for...inis:
for...ofiteratesoverthepropertyvaluesfor...initeratesthepropertynames
Loops
99
![Page 100: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/100.jpg)
EventsJavaScriptinthebrowserusesanevent-drivenprogrammingmodel.Everythingstartsbyfollowinganevent.ThisisanintroductiontoJavaScripteventsandhoweventhandlingworks
IntroductionJavaScriptinthebrowserusesanevent-drivenprogrammingmodel.
Everythingstartsbyfollowinganevent.
TheeventcouldbetheDOMisloaded,oranasynchronousrequestthatfinishesfetching,orauserclickinganelementorscrollingthepage,ortheusertypesonthekeyboard.
Therearealotofdifferentkindofevents.
EventhandlersYoucanrespondtoanyeventusinganEventHandler,whichisjustafunctionthat'scalledwhenaneventoccurs.
Events
100
![Page 101: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/101.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/102.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/103.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/104.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/105.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/106.jpg)
})
Events
106
![Page 107: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/107.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/108.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/109.jpg)
AsimpleeventloopexplanationLet'spickanexample:
constbar=()=>console.log('bar')
constbaz=()=>console.log('baz')
constfoo=()=>{
console.log('foo')
bar()
baz()
}
foo()
TheEventLoop
109
![Page 110: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/110.jpg)
Thiscodeprints
foo
bar
baz
asexpected.
Whenthiscoderuns,first foo()iscalled.Inside foo()wefirstcall bar(),thenwecallbaz().
Atthispointthecallstacklookslikethis:
Theeventlooponeveryiterationlooksifthere'ssomethinginthecallstack,andexecutesit:
TheEventLoop
110
![Page 111: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/111.jpg)
untilthecallstackisempty.
QueuingfunctionexecutionTheaboveexamplelooksnormal,there'snothingspecialaboutit:JavaScriptfindsthingstoexecute,runstheminorder.
TheEventLoop
111
![Page 112: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/112.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/113.jpg)
Hereistheexecutionorderforallthefunctionsinourprogram:
TheEventLoop
113
![Page 114: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/114.jpg)
Whyisthishappening?
TheMessageQueue
TheEventLoop
114
![Page 115: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/115.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/116.jpg)
Thisprints
foo
baz
shouldberightafterbaz,beforebar
bar
That'sabigdifferencebetweenPromises(andAsync/await,whichisbuiltonpromises)andplainoldasynchronousfunctionsthrough setTimeout()orotherplatformAPIs.
TheEventLoop
116
![Page 117: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/117.jpg)
AsynchronousprogrammingandcallbacksJavaScriptissynchronousbydefault,andissinglethreaded.Thismeansthatcodecannotcreatenewthreadsandruninparallel.Findoutwhatasynchronouscodemeansandhowitlookslike
AsynchronicityinProgrammingLanguagesComputersareasynchronousbydesign.
Asynchronousmeansthatthingscanhappenindependentlyofthemainprogramflow.
Inthecurrentconsumercomputers,everyprogramrunsforaspecifictimeslot,andthenitstopsitsexecutiontoletanotherprogramcontinueitsexecution.Thisthingrunsinacyclesofastthat'simpossibletonotice,andwethinkourcomputersrunmanyprogramssimultaneously,butthisisanillusion(exceptonmultiprocessormachines).
Programsinternallyuseinterrupts,asignalthat'semittedtotheprocessortogaintheattentionofthesystem.
Asynchronousprogrammingandcallbacks
117
![Page 118: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/118.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/119.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/120.jpg)
//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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/121.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/122.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/123.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/124.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/125.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/126.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/127.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/128.jpg)
}
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/129.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/130.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/131.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/132.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/133.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/134.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/135.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/136.jpg)
//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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/137.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/138.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/139.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/140.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/141.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/142.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/143.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/144.jpg)
;(function(){
'usestrict'
variable='hey'
})()(()=>{
'usestrict'
myname='Flavio'
})()
Assignmenterrors
JavaScriptsilentlyfailssomeconversionerrors.
InStrictMode,thosesilenterrorsnowraiseissues:
constundefined=1(()=>{
'usestrict'
undefined=1
})()
StrictMode
144
![Page 145: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/145.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/146.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/147.jpg)
//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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/148.jpg)
YoucanstillenableoctalnumbersinStrictModeusingthe 0oXXsyntax:
;(()=>{
'usestrict'
console.log(0o10)
})()
//8
Removed with
StrictModedisablesthe withkeyword,toremovesomeedgecasesandallowmoreoptimizationatthecompilerlevel.
StrictMode
148
![Page 149: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/149.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/150.jpg)
;(()=>{
/**/
})()
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/151.jpg)
~(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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/152.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/153.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/154.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/155.jpg)
/=: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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/156.jpg)
Mathoperators
156
![Page 157: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/157.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/158.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/159.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/160.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/161.jpg)
ESModulesESModulesistheECMAScriptstandardforworkingwithmodules.WhileNode.jshasbeenusingtheCommonJSstandardsinceyears,thebrowserneverhadamodulesystem,aseverymajordecisionsuchasamodulesystemmustbefirststandardizedbyECMAScriptandthenimplemented
IntroductiontoESModulesESModulesistheECMAScriptstandardforworkingwithmodules.
WhileNode.jshasbeenusingtheCommonJSstandardsinceyears,thebrowserneverhadamodulesystem,aseverymajordecisionsuchasamodulesystemmustbefirststandardizedbyECMAScriptandthenimplementedbythebrowser.
ThisstandardizationprocesscompletedwithES6andbrowsersstartedimplementingthisstandardtryingtokeepeverythingwellaligned,workingallinthesameway,andnowESModulesaresupportedinChrome,Safari,EdgeandFirefox(sinceversion60).
ESModules
161
![Page 162: Table of Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/162.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/163.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/164.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/165.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/166.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/167.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/168.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/169.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/170.jpg)
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 Contents · checking (something that TypeScript and Flow aim to improve) interpreted: it's commonly known as an interpreted language, which means that it does not need a](https://reader034.vdocuments.mx/reader034/viewer/2022042400/5f0ec8f87e708231d440ecd1/html5/thumbnails/171.jpg)
StatelessAstatelesscomponent,functionorclassisalsocalleddumbbecauseit'sincapableofhavingitsowndatatomakedecisions,soitsoutputorpresentationisentirelybasedonitsarguments.Thisimpliesthatpurefunctionsarestateless.
StrictmodeStrictmodeisanECMAScript5.1newfeature,whichcausestheJavaScriptruntimetocatchmoreerrors,butithelpsyouimprovetheJavaScriptcodebydenyingundeclaredvariablesandotherthingsthatmightcauseoverlookedissueslikeduplicatedobjectpropertiesandothersubtlethings.Hint:useit.Thealternativeis"sloppymode"whichisnotagoodthingevenlookingatthenamewegaveit.
TreeShakingTreeshakingmeansremoving"deadcode"fromthebundleyoushiptoyourusers.Ifyouaddsomecodethatyouneveruseinyourimportstatements,that'snotgoingtobesenttotheusersofyourapp,toreducefilesizeandloadingtime.
Glossary
171