Table of Contents · The JavaScript Beginner's Handbook follows the 80/20 rule: learn in 20%...

Preview:

Citation preview

TableofContentsPreface

IntroductiontoJavaScript

History

JustJavaScript

Syntax

Semicolons

Values

Variables

Types

Expressions

Operators

Precedence

Comparisons

Conditionals

Strings

Arrays

Loops

Functions

ArrowFunctions

Objects

Objectproperties

Objectmethods

Classes

Inheritance

AsynchonousProgrammingandCallbacks

Promises

2

AsyncandAwait

Variablesscope

Conclusion

3

PrefaceTheJavaScriptBeginner'sHandbook follows the80/20 rule: learn in20%ofthetimethe80%ofatopic.

Ifindthisapproachgivesawell-roundedoverview.

ThisbookdoesnottrytocovereverythingunderthesunrelatedtoJavaScript.It focuses on the core of the language, trying to simplify themore complextopics.

Ihopethecontentsofthisbookwillhelpyouachievewhatyouwant:learnthebasicsofJavaScript.

This book iswritten by Flavio. Ipublishweb development tutorials everydayonmywebsiteflaviocopes.com.

YoucanreachmeonTwitter@flaviocopes.

Enjoy!

4

IntroductiontoJavaScriptJavaScriptisoneofthemostpopularprogramminglanguagesintheworld.

Ibelieveit'sagreatlanguagetobeyourfirstprogramminglanguageever.

WemainlyuseJavaScripttocreate

websiteswebapplicationsserver-sideapplicationsusingNode.js

butJavaScriptisnotlimitedtothesethings,anditcanalsobeusedto

createmobileapplicationsusingtoolslikeReactNativecreateprogramsformicrocontrollersandtheinternetofthingscreatesmartwatchapplications

Itcanbasicallydoanything.It'ssopopularthateverythingnewthatshowsupisgoingtohavesomekindofJavaScriptintegrationatsomepoint.

JavaScriptisaprogramminglanguagethatis:

highlevel: itprovidesabstractionsthatallowyoutoignorethedetailsofthemachinewhereit'srunningon.Itmanagesmemoryautomaticallywithagarbagecollector, soyoucan focuson thecode insteadofmanagingmemory like other languages like C would need, and provides manyconstructs which allow you to deal with highly powerful variables andobjects.dynamic:opposedtostaticprogramminglanguages,adynamiclanguageexecutes at runtime many of the things that a static language does atcompile time.Thishasprosandcons,and itgivesuspowerful featureslike dynamic typing, late binding, reflection, functional programming,object runtime alteration, closures andmuchmore.Don't worry if thosethings are unknown to you - you'll know all of those at the end of thecourse.dynamicallytyped:avariabledoesnotenforceatype.Youcanreassign

5

anytypetoavariable,forexample,assigninganintegertoavariablethatholdsastring.loosely typed: as opposed to strong typing, loosely (or weakly) typedlanguagesdonot enforce the typeof anobject, allowingmore flexibilitybutdenyingustypesafetyandtypechecking(somethingthatTypeScript-whichbuildsontopofJavaScript-provides)interpreted: it's commonly known as an interpreted language, whichmeans that it does not need a compilation stage before a program canrun,asopposed toC,JavaorGo forexample. Inpractice,browsersdocompileJavaScriptbeforeexecutingit, forperformancereasons,butthisistransparenttoyou:thereisnoadditionalstepinvolved.multi-paradigm: the language does not enforce any particularprogrammingparadigm,unlikeJavaforexample,whichforcestheuseofobject-oriented programming, or C that forces imperative programming.You can write JavaScript using an object-oriented paradigm, usingprototypes and the new (as of ES6) classes syntax. You can writeJavaScriptinafunctionalprogrammingstyle,withitsfirst-classfunctions,oreveninanimperativestyle(C-like).

Incaseyou'rewondering,JavaScripthasnothingtodowithJava, it'sapoornamechoicebutwehavetolivewithit.

6

HistoryCreated in 1995, JavaScript has gone a very long way since its humblebeginnings.

It was the first scripting language that was supported natively by webbrowsers,andthankstothisitgainedacompetitiveadvantageoveranyotherlanguage and today it's still the only scripting language that we can use tobuildWebApplications.

Otherlanguagesexist,butallmustcompiletoJavaScript-ormorerecentlytoWebAssembly,butthisisanotherstory.

Inthebeginnings,JavaScriptwasnotnearlypowerfulasitistoday,anditwasmainly used for fancy animations and the marvel known at the time asDynamicHTML.

With the growing needs that the web platform demanded (and continues todemand),JavaScripthad the responsibility togrowaswell, toaccommodatetheneedsofoneofthemostwidelyusedecosystemsoftheworld.

JavaScriptisnowwidelyusedalsooutsideofthebrowser.TheriseofNode.jsin the last few years unlocked backend development, once the domain ofJava,Ruby,Python,PHPandmoretraditionalserver-sidelanguages.

JavaScript is now also the language powering databases and many moreapplications,andit'sevenpossibletodevelopembeddedapplications,mobileapps,TVsetsappsandmuchmore.Whatstartedasa tiny language insidethebrowserisnowthemostpopularlanguageintheworld.

7

JustJavaScriptSometimes it's hard to separate JavaScript from the features of theenvironmentitisusedin.

Forexample,the console.log()lineyoucanfindinmanycodeexamplesisnotJavaScript.Instead,it'spartofthevastlibraryofAPIsprovidedtousinthebrowser.Inthesameway,ontheserveritcanbesometimeshardtoseparatetheJavaScriptlanguagefeaturesfromtheAPIsprovidedbyNode.js.

IsaparticularfeatureprovidedbyReactorVue?Orisit"plainJavaScript",or"vanillaJavaScript"asoftencalled?

InthisbookItalkaboutJavaScript,thelanguage.

Without complicatingyour learningprocesswith things thatareoutsideof it,andprovidedbyexternalecosystems.

8

SyntaxInthislittleintroductionIwanttotellyouabout5concepts:

whitespacecasesensitivityliteralsidentifierscomments

WhitespaceJavaScriptdoesnotconsiderwhitespacemeaningful.Spacesandlinebreakscanbeaddedinanyfashionyoumightlike,eventhoughthisisintheory.

Inpractice,youwillmost likelykeepawelldefinedstyleandadhere towhatpeoplecommonlyuse,andenforce thisusinga linterorastyle toolsuchasPrettier.

Forexample,Iliketoalways2characterstoindent.

CasesensitiveJavaScript is case sensitive.A variable named something is different fromSomething.

Thesamegoesforanyidentifier.

LiteralsWedefineasliteralavaluethatiswritteninthesourcecode,forexample,anumber, a string, a boolean or also more advanced constructs, like ObjectLiteralsorArrayLiterals:

9

5

'Test'

true

['a','b']

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

IdentifiersAn identifier is a sequence of characters that can be used to identify avariable,afunction,anobject.Itcanstartwithaletter,thedollarsign$oranunderscore _,and itcancontaindigits.UsingUnicode,a lettercanbeanyallowedchar,forexample,anemojiߠ .

Test

test

TEST

_test

Test1

$test

ThedollarsigniscommonlyusedtoreferenceDOMelements.

SomenamesarereservedforJavaScriptinternaluse,andwecan'tusethemasidentifiers.

CommentsComments are one of the most important part of any program. In anyprogramminglanguage.Theyareimportantbecausetheyletusannotatethecodeandadd important information thatotherwisewouldnotbeavailable tootherpeople(orourselves)readingthecode.

InJavaScript,wecanwriteacommentonasinglelineusing //.Everythingafter//isnotconsideredascodebytheJavaScriptinterpreter.

10

Likethis:

//acomment

true//anothercomment

Anothertypeofcommentisamulti-linecomment.Itstartswith /*andendswith*/.

Everythinginbetweenisnotconsideredascode:

/*somekind

of

comment

*/

11

SemicolonsEverylineinaJavaScriptprogramisoptionallyterminatedusingsemicolons.

I said optionally, because the JavaScript interpreter is smart enough tointroducesemicolonsforyou.

Inmostcases,youcanomitsemicolonsaltogetherfromyourprograms.

This fact is very controversial, and you'll always find code that usessemicolonsandcodethatdoesnot.

My personal preference is to always avoid semicolons unless strictlynecessary.

12

ValuesAhellostringisavalue.Anumberlike12isavalue.

helloand 12 arevalues. string and number are the types of thosevalues.

The type is thekindofvalue, itscategory.Wehavemanydifferent types inJavaScript,andwe'lltalkaboutthemindetaillateron.Eachtypehasitsowncharacteristics.

Whenweneedtohaveareferencetoavalue,weassignittoavariable.Thevariablecanhaveaname,andthevalueiswhat'sstoredinavariable,sowecanlateraccessthatvaluethroughthevariablename.

13

VariablesAvariableisavalueassignedtoanidentifier,soyoucanreferenceanduseitlaterintheprogram.

ThisisbecauseJavaScriptislooselytyped,aconceptyou'll frequentlyhearabout.

Avariablemustbedeclaredbeforeyoucanuseit.

Wehave2mainwaystodeclarevariables.Thefirstistouseconst:

consta=0

Thesecondwayistouselet:

leta=0

What'sthedifference?

const defines a constant reference to a value. Thismeans the referencecannotbechanged.Youcannotreassignanewvaluetoit.

Usingletyoucanassignanewvaluetoit.

Forexample,youcannotdothis:

consta=0

a=1

Becauseyou'llgetanerror:TypeError:Assignmenttoconstantvariable..

Ontheotherhand,youcandoitusinglet:

leta=0

a=1

14

const does notmean "constant" in the way some other languages like Cmean. In particular, it doesnotmean the value cannot change - itmeans itcannotbereassigned.Ifthevariablepointstoanobjectoranarray(we'llseemoreaboutobjectsandarrayslater)thecontentoftheobjectorthearraycanfreelychange.

Constvariablesmustbeinitializedatthedeclarationtime:

consta=0

butletvaluescanbeinitializedlater:

leta

a=0

Youcandeclaremultiplevariablesatonceinthesamestatement:

consta=1,b=2

letc=1,d=2

Butyoucannotredeclarethesamevariablemorethanonetime:

leta=1

leta=2

oryou'dgeta"duplicatedeclaration"error.

Myadviceistoalwaysuse constandonlyuse letwhenyouknowyou'llneed to reassignavalue to thatvariable.Why?Because the lesspowerourcodehas, thebetter. Ifweknowavaluecannotbe reassigned, it'sone lesssourceforbugs.

Nowthatwesawhowtoworkwithconstandlet,Iwanttomentionvar.

15

Until2015, varwastheonlywaywecoulddeclareavariableinJavaScript.Today,amoderncodebasewillmostlikelyjustuse constand let.Therearesomefundamentaldifferenceswhich Idetail inthispostbut ifyou're juststartingout,youmightnotcareabout.Justuseconstandlet.

16

TypesVariablesinJavaScriptdonothaveanytypeattached.

Theyareuntyped.

Onceyouassignavaluewithsometypetoavariable,youcanlaterreassignthevariabletohostavalueofanyothertype,withoutanyissue.

In JavaScript we have 2 main kinds of types: primitive types and objecttypes.

PrimitivetypesPrimitivetypesare

numbersstringsbooleanssymbols

Andtwospecialtypes:nullandundefined.

ObjecttypesAnyvaluethat'snotofaprimitivetype(astring,anumber,aboolean,nullorundefined)isanobject.

Object typeshavepropertiesandalsohavemethods thatcanacton thoseproperties.

We'lltalkmoreaboutobjectslateron.

17

18

ExpressionsAnexpression isa singleunit of JavaScript code that theJavaScriptenginecanevaluate,andreturnavalue.

Expressionscanvaryincomplexity.

Westartfromtheverysimpleones,calledprimaryexpressions:

2

0.02

'something'

true

false

this//thecurrentscope

undefined

i//whereiisavariableoraconstant

Arithmetic expressionsareexpressions that takea variable andanoperator(moreonoperatorssoon),andresultintoanumber:

1/2

i++

i-=2

i*2

Stringexpressionsareexpressionsthatresultintoastring:

'A'+'string'

Logical expressionsmakeuseof logical operatorsand resolve toabooleanvalue:

a&&b

a||b

!a

19

More advanced expressions involve objects, functions, and arrays, and I'llintroducethemlater.

20

OperatorsOperatorsallowyoutogettwosimpleexpressionsandcombinethemtoformamorecomplexexpression.

We can classify operators based on the operands they work with. Someoperatorsworkwith1operand.Mostwith2operands.Justoneoperatorworkswith3operands.

Inthisfirstintroductiontooperators,we'llintroducetheoperatorsyouaremostlikelyfamilarwith:binaryoperators.

I already introduced one when talking about variables: the assignmentoperator=.Youuse=toassignavaluetoavariable:

letb=2

Let'snow introduceanother setofbinaryoperators that youalready familiarwith,frombasicmath.

Theadditionoperator(+)

constthree=1+2

constfour=three+1

The+operatoralsoservesasstringconcatenationifyouusestrings,sopayattention:

constthree=1+2

three+1//4

'three'+1//three1

Thesubtractionoperator(-)

21

consttwo=4-2

Thedivisionoperator(/)

Returnsthequotientofthefirstoperatorandthesecond:

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

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

If you divide by zero, JavaScript does not raise any error but returns theInfinityvalue(or-Infinityifthevalueisnegative).

1/0//Infinity

-1/0//-Infinity

Theremainderoperator(%)

Theremainderisaveryusefulcalculationinmanyusecases:

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

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

A reminder by zero is always NaN , a special value that means "Not aNumber":

1%0//NaN

-1%0//NaN

Themultiplicationoperator(*)

Multiplytwonumbers

1*2//2

-1*2//-2

22

Theexponentiationoperator(**)

Raisethefirstoperandtothepowersecondoperand

1**2//1

2**1//2

2**2//4

2**8//256

8**2//64

23

PrecedenceEverycomplexstatementwithmultipleoperatorsinthesamelinewillintroduceprecedenceproblems.

Takethisexample:

leta=1*2+5/2%2

Theresultis2.5,butwhy?

Whatoperationsareexecutedfirst,andwhichneedtowait?

Some operations have more precedence than the others. The precedencerulesarelistedinthistable:

Operator Description

*/% multiplication/division

+- addition/subtraction

= assignment

Operationsonthesamelevel(like +and-)areexecutedintheordertheyarefound,fromlefttoright.

Followingtheserules,theoperationabovecanbesolvedinthisway:

leta=1*2+5/2%2

leta=2+5/2%2

leta=2+2.5%2

leta=2+0.5

leta=2.5

24

ComparisonsAfter assignment and math operators, the third set of operators I want tointroduceisconditionaloperators.

Youcanusethefollowingoperatorstocomparetwonumbers,ortwostrings.

Comparison operators always returns a boolean, a value that's true orfalse).

Thosearedisequalitycomparisonoperators:

<means"lessthan"<=means"minusthan,orequalto">means"greaterthan">=means"greaterthan,orequalto"

Example:

leta=2

a>=1//true

Inadditiontothose,wehave4equalityoperators.Theyaccept twovalues,andreturnaboolean:

===checksforequality!==checksforinequality

Notethatwealsohave==and!=inJavaScript,butIhighlysuggesttoonlyuse===and!==becausetheycanpreventsomesubtleproblems.

25

ConditionalsWiththecomparisonoperatorsinplace,wecantalkaboutconditionals.

An if statement is used to make the program take a route, or another,dependingontheresultofanexpressionevaluation.

Thisisthesimplestexample,whichalwaysexecutes:

if(true){

//dosomething

}

onthecontrary,thisisneverexecuted:

if(false){

//dosomething(?never?)

}

Theconditionalcheckstheexpressionyoupasstoitfortrueorfalsevalue.Ifyoupassanumber, thatalwaysevaluatestotrueunless it's0. Ifyoupassastring, it always evaluates to true unless it's an empty string. Those aregeneralrulesofcastingtypestoaboolean.

Didyounoticethecurlybraces?Thatiscalledablock,anditisusedtogroupalistofdifferentstatements.

Ablockcanbeputwhereveryoucanhaveasinglestatement.Andifyouhaveasinglestatement toexecuteafter theconditionals, youcanomit theblock,andjustwritethestatement:

if(true)doSomething()

ButIalwaysliketousecurlybracestobemoreclear.

26

ElseYoucanprovideasecondparttotheifstatement:else.

Youattacha statement that is going to beexecuted if the if condition isfalse:

if(true){

//dosomething

}else{

//dosomethingelse

}

Since else accepts a statement, you can nest another if/else statementinsideit:

if(a===true){

//dosomething

}elseif(b===true){

//dosomethingelse

}else{

//fallback

}

27

StringsAstringisasequenceofcharacters.

Itcanbealsodefinedasastringliteral,whichisenclosedinquotesordoublequotes:

'Astring'

"Anotherstring"

I personallyprefer singlequotesall the time,andusedoublequotesonly inHTMLtodefineattributes.

Youassignastringvaluetoavariablelikethis:

constname='Flavio'

Youcandeterminethelengthofastringusingthelengthpropertyofit:

'Flavio'.length//6

constname='Flavio'

name.length//6

Thisisanemptystring:''.Itslengthpropertyis0:

''.length//0

Twostringscanbejoinedusingthe+operator:

"A"+"string"

Youcanusethe+operatortointerpolatevariables:

constname='Flavio'

28

"Mynameis"+name//MynameisFlavio

Another way to define strings is to use template literals, defined insidebackticks.Theyareespeciallyuseful tomakemultilinestringsmuchsimpler.With single or double quotes you can't define amultiline string easily: you'dneedtouseescapingcharacters.

Once a template literal is opened with the backtick, you just press enter tocreateanewline,withnospecialcharacters,andit'srenderedas-is:

conststring=`Hey

this

string

isawesome!`

Template literals are also great because they provide an easy way tointerpolatevariablesandexpressionsintostrings.

Youdosobyusingthe${...}syntax:

constvar='test'

conststring=`something${var}`

//somethingtest

insidethe${}youcanaddanything,evenexpressions:

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

conststring2=`something

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

29

ArraysAnarrayisacollectionofelements.

ArraysinJavaScriptarenotatypeontheirown.

Arraysareobjects.

Wecaninitializeanemptyarrayinthese2differentways:

consta=[]

consta=Array()

Thefirstisusingthearrayliteralsyntax.ThesecondusestheArraybuilt-infunction.

Youcanpre-fillthearrayusingthissyntax:

consta=[1,2,3]

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

Anarraycanholdanyvalue,evenvalueofdifferenttypes:

consta=[1,'Flavio',['a','b']]

Since we can add an array into an array, we can create multi-dimensionalarrays,whichhaveveryusefulapplications(e.g.amatrix):

constmatrix=[

[1,2,3],

[4,5,6],

[7,8,9]

]

matrix[0][0]//1

matrix[2][0]//7

30

Youcanaccessanyelementofthearraybyreferencingitsindex,whichstartsfromzero:

a[0]//1

a[1]//2

a[2]//3

Youcaninitializeanewarraywithasetofvaluesusingthissyntax,whichfirstinitializesanarrayof12elements,andfillseachelementwiththe0number:

Array(12).fill(0)

You can get the number of elements in the array by checking its lengthproperty:

consta=[1,2,3]

a.length//3

Note thatyoucanset the lengthof thearray. Ifyouassignabiggernumberthan the arrays current capacity, nothing happens. If you assign a smallernumber,thearrayiscutatthatposition:

consta=[1,2,3]

a//[1,2,3]

a.length=2

a//[1,2]

HowtoaddanitemtoanarrayWecanaddanelementattheendofanarrayusingthepush()method:

a.push(4)

31

We can add an element at the beginning of an array using the unshift()method:

a.unshift(0)

a.unshift(-2,-1)

HowtoremoveanitemfromanarrayWecanremoveanitemfromtheendofanarrayusingthepop()method:

a.pop()

Wecan removean item from thebeginningof anarrayusing the shift()method:

a.shift()

HowtojointwoormorearraysYoucanjoinmultiplearraysbyusingconcat():

consta=[1,2]

constb=[3,4]

constc=a.concat(b)//[1,2,3,4]

a//[1,2]

b//[3,4]

Youcanalsousethespreadoperator(...)inthisway:

consta=[1,2]

constb=[3,4]

constc=[...a,...b]

c//[1,2,3,4]

32

HowtofindaspecificiteminthearrayYoucanusethefind()methodofanarray:

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

//returntrueorfalse

})

Returnsthefirstitemthatreturnstrue.Returnsundefinediftheelementisnotfound.

Acommonlyusedsyntaxis:

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

Theabovelinewillreturnthefirstelementinthearraythathasid===my_id.

findIndex()workssimilarlytofind(),butreturnstheindexofthefirstitemthatreturnstrue,andifnotfound,itreturnsundefined:

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

//returntrueorfalse

})

Anothermethodisincludes():

a.includes(value)

Returnstrueifacontainsvalue.

a.includes(value,i)

Returnstrueifacontainsvalueafterthepositioni.

33

34

LoopsLoopsareoneofthemaincontrolstructuresofJavaScript.

Withaloopwecanautomateandrepeatindefinitelyablockofcode,forhowmanytimeswewantittorun.

JavaScriptprovidesmanywaytoiteratethroughloops.

Iwanttofocuson3ways:

whileloopsforloopsfor..ofloops

while

ThewhileloopisthesimplestloopingstructurethatJavaScriptprovidesus.

Weaddaconditionafterthe whilekeyword,andweprovideablockthatisrununtiltheconditionevaluatestotrue.

Example:

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

leti=0

while(i<list.length){

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

console.log(i)//index

i=i+1

}

Youcaninterruptawhileloopusingthebreakkeyword,likethis:

while(true){

if(somethingIsTrue)break

}

35

and if you decide that in themiddle of a loop you want to skip the currentiteration,youcanjumptothenextiterationusingcontinue:

while(true){

if(somethingIsTrue)continue

//dosomethingelse

}

Verysimilarto while,wehave do..while loops.It'sbasicallythesameaswhile,excepttheconditionisevaluatedafterthecodeblockisexecuted.

Thismeanstheblockisalwaysexecutedatleastonce.

Example:

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

leti=0

do{

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

console.log(i)//index

i=i+1

}while(i<list.length)

for

ThesecondveryimportantloopingstructureinJavaScriptistheforloop.

We use the for keyword and we pass a set of 3 instructions: theinitialization,thecondition,andtheincrementpart.

Example:

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

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

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

console.log(i)//index

36

}

Justlikewith whileloops,youcaninterrupta forloopusing breakandyoucanfastforwardtothenextiterationofaforloopusingcontinue.

for...of

Thisloopisrelativelyrecent(introducedin2015)andit'sasimplifiedversionoftheforloop:

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

for(constvalueoflist){

console.log(value)//value

}

37

FunctionsIn any moderately complex JavaScript program, everything happens insidefunctions.

Functionsareacore,essentialpartofJavaScript.

Whatisafunction?

Afunctionisablockofcode,selfcontained.

Here'safunctiondeclaration:

functiongetData(){

//dosomething

}

Afunctioncanberunanytimesyouwantbyinvokingit,likethis:

getData()

Afunctioncanhaveoneormoreargument:

functiongetData(){

//dosomething

}

functiongetData(color){

//dosomething

}

functiongetData(color,age){

//dosomething

}

Whenwecanpassanargument,weinvokethefunctionpassingparameters:

38

functiongetData(color,age){

//dosomething

}

getData('green',24)

getData('black')

Note that in thesecond invokation Ipassed the black stringparameterasthe colorargument,butno age. In thiscase, age inside the function isundefined.

Wecancheckifavalueisnotundefinedusingthisconditional:

functiongetData(color,age){

//dosomething

if(typeofage!=='undefined'){

//...

}

}

typeofisaunaryoperatorthatallowsustocheckthetypeofavariable.

Youcanalsocheckinthisway:

functiongetData(color,age){

//dosomething

if(age){

//...

}

}

although theconditionalwillalsobe true if age is null, 0 oranemptystring.

Youcanhavedefaultvaluesforparameters,incasetheyarenotpassed:

functiongetData(color='black',age=25){

//dosomething

39

}

Youcanpassanyvalueasaparameter:numbers,strings,booleans,arrays,objects,andalsofunctions.

Afunctionhasareturnvalue.Bydefaultafunctionreturnsundefined,unlessyouaddareturnkeywordwithavalue:

functiongetData(){

//dosomething

return'hi!'

}

Wecanassignthisreturnvaluetoavariablewhenweinvokethefunction:

functiongetData(){

//dosomething

return'hi!'

}

letresult=getData()

resultnowholdsastringwiththethehi!value.

Youcanonlyreturnonevalue.

Toreturnmultiplevalues,youcanreturnanobject,oranarray,likethis:

functiongetData(){

return['Flavio',37]

}

let[name,age]=getData()

Functionscanbedefinedinsideotherfunctions:

constgetData=()=>{

constdosomething=()=>{}

40

dosomething()

return'test'

}

The nested function cannot be called from the outside of the enclosingfunction.

Youcanreturnafunctionfromafunction,too.

41

ArrowFunctionsArrowfunctionsarearecentintroductiontoJavaScript.

Theyareveryoftenusedinsteadof"regular"functions,theoneIdescribedinthepreviouschapter.You'llfindbothformsusedeverywhere.

Visually,theyallowsyoutowritefunctionswithashortersyntax,from:

functiongetData(){

//...

}

to

()=>{

//...

}

But..noticethatwedon'thaveanamehere.

Arrowfunctionsareanonymous.Wemustassignthemtoavariable.

Wecanassignaregularfunctiontoavariable,likethis:

letgetData=functiongetData(){

//...

}

Whenwedoso,wecanremovethenamefromthefunction:

letgetData=function(){

//...

}

andinvokethefunctionusingthevariablename:

42

letgetData=function(){

//...

}

getData()

That'sthesamethingwedowitharrowfunctions:

letgetData=()=>{

//...

}

getData()

If the function body contains just a single statement, you can omit theparenthesesandwriteallonasingleline:

constgetData=()=>console.log('hi!')

Parametersarepassedintheparentheses:

constgetData=(param1,param2)=>

console.log(param1,param2)

If you have one (and just one) parameter, you could omit the parenthesescompletely:

constgetData=param=>console.log(param)

Arrow functions allow you to have an implicit return: values are returnedwithouthavingtousethereturnkeyword.

Itworkswhenthereisaon-linestatementinthefunctionbody:

constgetData=()=>'test'

getData()//'test'

43

Likewithregularfunctions,wecanhavedefaultparameters:

Youcanhavedefaultvaluesforparameters,incasetheyarenotpassed:

constgetData=(color='black',

age=2)=>{

//dosomething

}

andwecanonlyreturnonevalue.

Arrowfunctionscancontainotherarrowfunction,oralsoregularfunctions.

The are very similar, so youmight ask why they were introduced? The bigdifference with regular functions is when they are used as object methods.Thisissomethingwe'llsoonlookinto.

44

ObjectsAny value that's not of a primitive type (a string, a number, a boolean, asymbol,null,orundefined)isanobject.

Here'showwedefineanobject:

constcar={

}

Thisistheobjectliteralsyntax,whichisoneofthenicestthingsinJavaScript.

YoucanalsousethenewObjectsyntax:

constcar=newObject()

AnothersyntaxistouseObject.create():

constcar=Object.create()

Youcanalsoinitializeanobjectusingthenewkeywordbeforeafunctionwithacapital letter.Thisfunctionservesasaconstructor for thatobject. In there,wecaninitializetheargumentswereceiveasparameters, tosetupthe initialstateoftheobject:

functionCar(brand,model){

this.brand=brand

this.model=model

}

Weinitializeanewobjectusing

constmyCar=newCar('Ford','Fiesta')

myCar.brand//'Ford'

45

myCar.model//'Fiesta'

Objectsarealwayspassedbyreference.

Ifyouassignavariablethesamevalueofanother,ifit'saprimitivetypelikeanumberorastring,theyarepassedbyvalue:

Takethisexample:

letage=36

letmyAge=age

myAge=37

age//36

constcar={

color:'blue'

}

constanotherCar=car

anotherCar.color='yellow'

car.color//'yellow'

Evenarraysorfunctionsare,underthehoods,objects,soit'sveryimportanttounderstandhowtheywork.

46

ObjectpropertiesObjects haveproperties,which are composed by a label associatedwith avalue.

The value of a property can be of any type,whichmeans that it can be anarray, a function, and it can even be an object, as objects can nest otherobjects.

Thisistheobjectliteralsyntaxwesawinthepreviouschapter:

constcar={

}

Wecandefineacolorpropertyinthisway:

constcar={

color:'blue'

}

herewehaveacarobjectwithapropertynamedcolor,withvalueblue.

Labelscanbeanystring,butbewarespecialcharacters:ifIwantedtoincludeacharacternotvalidasavariablename in thepropertyname, Iwouldhavehadtousequotesaroundit:

constcar={

color:'blue',

'thecolor':'blue'

}

Invalidvariablenamecharacters includespaces,hyphens,andotherspecialcharacters.

47

Asyousee,whenwehavemultipleproperties,weseparateeachpropertywithacomma.

Wecanretrievethevalueofapropertyusing2differentsyntaxes.

Thefirstisdotnotation:

car.color//'blue'

The second (which is the only one we can use for properties with invalidnames),istousesquarebrackets:

car['thecolor']//'blue'

Ifyouaccessanunexistingproperty,you'llgettheundefinedvalue:

car.brand//undefined

Assaid,objectscanhavenestedobjectsasproperties:

constcar={

brand:{

name:'Ford'

},

color:'blue'

}

Inthisexample,youcanaccessthebrandnameusing

car.brand.name

or

car['brand']['name']

48

Youcansetthevalueofapropertywhenyoudefinetheobject.

Butyoucanalwaysupdateitlateron:

constcar={

color:'blue'

}

car.color='yellow'

car['color']='red'

Andyoucanalsoaddnewpropertiestoanobject:

car.model='Fiesta'

car.model//'Fiesta'

Giventheobject

constcar={

color:'blue',

brand:'Ford'

}

youcandeleteapropertyfromthisobjectusing

deletecar.brand

49

ObjectmethodsItalkedaboutfunctionsinapreviouschapter.

Functions can be assigned to a function property, and in this case they arecalledmethods.

In this example, the start property has a function assigned, andwe caninvokeitbyusingthedotsyntaxweusedforproperties,withtheparenthesesattheend:

constcar={

brand:'Ford',

model:'Fiesta',

start:function(){

console.log('Started')

}

}

car.start()

Insideamethoddefinedusingafunction(){}syntaxwehaveaccesstotheobjectinstancebyreferencingthis.

In the following example, we have access to the brand and model

propertiesvaluesusingthis.brandandthis.model:

constcar={

brand:'Ford',

model:'Fiesta',

start:function(){

console.log(`Started

${this.brand}${this.model}`)

}

}

car.start()

50

It's important to note this distinction between regular functions and arrowfunctions:wedon'thaveaccesstothisifweuseanarrowfunction:

constcar={

brand:'Ford',

model:'Fiesta',

start:()=>{

console.log(`Started

${this.brand}${this.model}`)//notgoingtowork

}

}

car.start()

Thisisbecausearrowfunctionsarenotboundtotheobject.

Thisisthereasonwhyregularfunctionsareoftenusedasobjectmethods.

Methodscanacceptparameters,likeregularfunctions:

constcar={

brand:'Ford',

model:'Fiesta',

goTo:function(destination){

console.log(`Goingto${destination}`)

}

}

car.goTo('Rome')

51

ClassesWe talked about objects, which are one of the most interesting parts ofJavaScript.

Inthischapterwe'llgouponelevel,introducingclasses.

What are classes?They are away to define a commonpattern formultipleobjects.

Let'stakeapersonobject:

constperson={

name:'Flavio'

}

We can create a class named Person (note the capital P , a conventionwhenusingclasses),thathasanameproperty:

classPerson{

name

}

Nowfromthisclass,weinitializeaflavioobjectlikethis:

constflavio=newPerson()

flavioiscalledaninstanceofthePersonclass.

Wecansetthevalueofthenameproperty:

flavio.name='Flavio'

andwecanaccessitusing

52

flavio.name

likewedoforobjectproperties.

Classescanholdproperties,likename,andmethods.

Methodsaredefinedinthisway:

classPerson{

hello(){

return'Hello,IamFlavio'

}

}

andwecaninvokemethodsonaninstanceoftheclass:

classPerson{

hello(){

return'Hello,IamFlavio'

}

}

constflavio=newPerson()

flavio.hello()

There is a specialmethod called called constructor() thatwe can use toinitializetheclasspropertieswhenwecreateanewobjectinstance.

Itworkslikethis:

classPerson{

constructor(name){

this.name=name

}

hello(){

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

}

}

53

Notehowweusethistoaccesstheobjectinstance.

Now we can instantiate a new object from the class, passing a string, andwhenwecallhello,we'llgetapersonalizedmessage:

constflavio=newPerson('flavio')

flavio.hello()//'Hello,Iamflavio.'

When the object is initialized, the constructor method is called, with anyparameterspassed.

Normallymethodsaredefinedontheobjectinstance,notontheclass.

Youcandefineamethodas static toallow it tobeexecutedontheclassinstead:

classPerson{

staticgenericHello(){

return'Hello'

}

}

Person.genericHello()//Hello

Thisisveryuseful,attimes.

54

InheritanceA class can extend another class, and objects initialized using that classinheritallthemethodsofbothclasses.

SupposewehaveaclassPerson:

classPerson{

hello(){

return'Hello,IamaPerson'

}

}

WecandefineanewclassProgrammerthatextendsPerson:

classProgrammerextendsPerson{

}

NowifweinstantiateanewobjectwithclassProgrammer,ithasaccesstothehello()method:

constflavio=newProgrammer()

flavio.hello()//'Hello,IamaPerson'

Insideachildclass,youcanreferencetheparentclasscallingsuper():

classProgrammerextendsPerson{

hello(){

returnsuper.hello()+

'.Iamalsoaprogrammer.'

}

}

constflavio=newProgrammer()

flavio.hello()

55

TheaboveprogramprintsHello,IamaPerson.Iamalsoaprogrammer..

56

AsynchonousProgrammingandCallbacksMostofthetime,JavaScriptcodeisransynchronously.

Thismeansthatalineofcodeisexecuted,thenthenextoneisexecuted,andsoon.

Everything is as you expect, and how it works in most programminglanguages.

However there are times when you cannot just wait for a line of code toexecute.

You can't just wait 2 seconds for a big file to load, and halt the programcompletely.

You can't just wait for a network resource to be downloaded, before doingsomethingelse.

JavaScriptsolvesthisproblemusingcallbacks.

Oneofthesimplestexamplesofhowtousecallbacksistimers.TimersarenotpartofJavaScript,buttheyareprovidedbythebrowser,andNode.js.Letmetalkaboutoneofthetimerswehave:setTimeout().

The setTimeout() functionaccepts2arguments:a function,andanumber.Thenumberisthemillisecondsthatmustpassbeforethefunctionisran.

Example:

setTimeout(()=>{

//runsafter2seconds

console.log('insidethefunction')

},2000)

57

Thefunctioncontainingthe console.log('insidethefunction') linewillbeexecutedafter2seconds.

If you add a console.log('before') prior to the function, andconsole.log('after')afterit:

console.log('before')

setTimeout(()=>{

//runsafter2seconds

console.log('insidethefunction')

},2000)

console.log('after')

Youwillseethishappeninginyourconsole:

before

after

insidethefunction

Thecallbackfunctionisexecutedasynchronously.

Thisisaverycommonpatternwhenworkingwiththefilesystem,thenetwork,events,ortheDOMinthebrowser.

All of the things I mentioned are not "core" JavaScript, so they are notexplained in this handbook, but you'll find lots of examples in my otherhandbooksavailableathttps://flaviocopes.com.

Here'showwecanimplementcallbacksinourcode.

Wedefineafunctionthatacceptsacallbackparameter,whichisafunction.

Whenthecodeisreadytoinvokethecallback,weinvokeitpassingtheresult:

constdoSomething=callback=>{

//dothings

//dothings

constresult=/*..*/

callback(result)

58

}

Codeusingthisfunctionwoulduseitlikethis:

doSomething(result=>{

console.log(result)

})

59

PromisesPromisesareanalternativewaytodealwithasynchronouscode.

Aswesawinthepreviouschapter,withcallbackswe'dbepassingafunctiontoanother function call, thatwouldbe calledwhen the functionhas finishedprocessing.

Likethis:

doSomething(result=>{

console.log(result)

})

When the doSomething() code ends, it calls the function received as a aparameter:

constdoSomething=callback=>{

//dothings

//dothings

constresult=/*..*/

callback(result)

}

Themainproblemwiththisapproachisthatifweneedtousetheresultofthisfunction in the rest of our code, all our code must be nested inside thecallback,andifwehavetodo2-3callbacksweenterinwhatisusuallydefined"callbackhell"withmanylevelsoffunctionsindentedintootherfunctions:

doSomething(result=>{

doSomethingElse(anotherResult=>{

doSomethingElseAgain(yetAnotherResult=>{

console.log(result)

})

})

})

60

Promisesareonewaytodealwiththis.

Insteadofdoing:

doSomething(result=>{

console.log(result)

})

Wecallapromise-basedfunctioninthisway:

doSomething()

.then(result=>{

console.log(result)

})

Wefirstcallthefunction,thenwehavea then()methodthatiscalledwhenthefunctionends.

Theindentationdoesnotmatter,butyou'lloftenusethisstyleforclarity.

It'scommontodetecterrorsusingacatch()method:

doSomething()

.then(result=>{

console.log(result)

})

.catch(error=>{

console.log(error)

})

Now, to be able to use this syntax, the doSomething() functionimplementationmustbealittlebitspecial.ItmustusethePromisesAPI.

Insteadofdeclaringitasanormalfunction:

constdoSomething=()=>{

}

61

Wedeclareitasapromiseobject:

constdoSomething=newPromise()

andwepassafunctioninthePromiseconstructor:

constdoSomething=newPromise(()=>{

})

This functionreceives2parameters.Thefirst isa functionwecall toresolvethepromise,thesecondafunctionwecalltorejectthepromise.

constdoSomething=newPromise(

(resolve,reject)=>{

})

Resolvingapromisemeanscomplete itsuccessfully (which results incallingthethen()methodinwhousesit).

Rejectingapromisemeansendingitwithanerror(whichresultsincallingthecatch()methodinwhousesit).

Here'show:

constdoSomething=newPromise(

(resolve,reject)=>{

//somecode

constsuccess=/*...*/

if(success){

resolve('ok')

}else{

reject('thiserroroccurred')

}

}

)

62

Wecanpassaparametertotheresolveandrejectfunctions,ofanytypewewant.

63

AsyncandAwaitAsyncfunctionsareahigherlevelabstractionoverpromises.

Anasyncfunctionreturnsapromise,likeinthisexample:

constgetData=()=>{

returnnewPromise((resolve,reject)=>{

setTimeout(()=>

resolve('somedata'),2000)

})

}

Any code that want to use this function will use the async keyword rightbeforethefunction:

constdata=awaitgetData()

anddoingso,anydatareturnedbythepromiseisgoingtobeassignedtothedatavariable.

Inourcase,thedataisthe"somedata"string.

Withoneparticularcaveat:wheneverweusetheawaitkeyword,wemustdosoinsideafunctiondefinedasasync.

Likethis:

constdoSomething=async()=>{

constdata=awaitgetData()

console.log(data)

}

TheAsync/awaitduoallowsus tohaveacleanercodeandasimplementalmodeltoworkwithasynchronouscode.

64

Asyoucanseeintheexampleabove,ourcodelooksverysimple.Compareittocodeusingpromises,orcallbackfunctions.

Andthisisaverysimpleexample,themajorbenefitswillarisewhenthecodeismuchmorecomplex.

Asanexample,here'showyouwouldgetaJSONresourceusing theFetchAPI,andparseit,usingpromises:

constgetFirstUserData=()=>{

//getuserslist

returnfetch('/users.json')

//parseJSON

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

//pickfirstuser

.then(users=>users[0])

//getuserdata

.then(user=>

fetch(`/users/${user.name}`))

//parseJSON

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

}

getFirstUserData()

Andhereisthesamefunctionalityprovidedusingawait/async:

constgetFirstUserData=async()=>{

//getuserslist

constresponse=awaitfetch('/users.json')

//parseJSON

constusers=awaitresponse.json()

//pickfirstuser

constuser=users[0]

//getuserdata

constuserResponse=

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

//parseJSON

constuserData=awaituser.json()

returnuserData

}

65

getFirstUserData()

66

VariablesscopeWhenIintroducedvariables,Italkedaboutusingconst,let,andvar.

Scopeisthesetofvariablesthat'svisibletoapartoftheprogram.

InJavaScriptwehaveaglobalscope,blockscopeandfunctionscope.

Ifavariableisdefinedoutsideofafunctionorblock,it'sattachedtotheglobalobjectand ithasaglobalscope,whichmean it'savailable ineverypartofaprogram.

There is a very important difference between var , let and constdeclarations.

Avariabledefinedasvarinsideafunctionisonlyvisibleinsidethatfunction.Similarlytoafunctionarguments:

Avariabledefinedas constor letontheotherhandisonlyvisibleinsidetheblockwhereitisdefined.

Ablockisasetofinstructionsgroupedintoapairofcurlybraces,liketheoneswecanfindinsideanifstatementoraforloop.Andafunction,too.

It'simportanttounderstandthatablockdoesnotdefineanewscopeforvar,butitdoesforletandconst.

Thishasverypracticalimplications.

Supposeyoudefineavarvariableinsideanifconditionalinafunction

functiongetData(){

if(true){

vardata='somedata'

console.log(data)

}

}

Ifyoucallthisfunction,you'llgetsomedataprintedtotheconsole.

67

Ifyoutrytomoveconsole.log(data)aftertheif,itstillworks:

functiongetData(){

if(true){

vardata='somedata'

}

console.log(data)

}

Butifyouswitchvardatatoletdata:

functiongetData(){

if(true){

letdata='somedata'

}

console.log(data)

}

You'llgetanerror:ReferenceError:dataisnotdefined.

This is because var is function scoped, and there's a special thinghappeninghere,calledhoisting.Inshort,thevardeclarationismovedtothetopoftheclosestfunctionbyJavaScript,beforeitrunsthecode.MoreorlessthisiswhatthefunctionlooksliketoJS,internally:

functiongetData(){

vardata

if(true){

data='somedata'

}

console.log(data)

}

This iswhyyoucanalso console.log(data) at the top of a function, evenbeforeit'sdeclared,andyou'llgetundefinedasavalueforthatvariable:

functiongetData(){

console.log(data)

68

if(true){

vardata='somedata'

}

}

but if you switch to let, you'll get an error ReferenceError: data is notdefined,becausehoistingdoesnothappentoletdeclarations.

constfollowsthesamerulesaslet:it'sblockscoped.

Itcanbetrickyatfirst,butonceyourealizethisdifference,thenyou'llseewhyvarisconsideredabadpracticenowadayscomparedto let:theydohavelessmovingparts,and their scope is limited to theblock,whichalsomakesthemverygoodasloopvariables,becausetheyceasetoexistafteraloophasended:

functiondoLoop(){

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

console.log(i)

}

console.log(i)

}

doLoop()

Whenyouexittheloop,iwillbeavalidvariablewithvalue10.

If you switch to let , if you try to console.log(i) will result in an errorReferenceError:iisnotdefined.

69

ConclusionThanksalotforreadingthisbook.

IhopeitwillinspireyoutoknowmoreaboutJavaScript.

FormoreonJavaScript,checkoutmyblogflaviocopes.com.

Sendanyfeedback,errataoropinionsathey@flaviocopes.com

70