table of contents · callbacks promises generators program performance benchmarking & tuning...
TRANSCRIPT
-
1.1
1.2
1.2.1
1.2.2
1.2.3
1.2.4
1.2.5
1.2.6
1.3
1.3.1
1.3.2
1.3.3
1.3.4
1.3.5
1.3.6
1.3.7
1.3.8
1.3.9
1.3.10
1.3.11
1.4
1.4.1
1.4.2
1.4.3
1.4.4
1.4.5
1.4.6
1.4.7
1.4.8
1.4.9
TableofContentsIntroduction
up&going
Foreword
Preface
IntoProgramming
IntoJavaScript
IntoYDKJS
Acknowledgments
Scope&Closures
Foreword
Preface
WhatisScope?
LexicalScope
Functionvs.BlockScope
Hoisting
ScopeClosure
DynamicScope
PolyfillingBlockScope
Lexical-this
Acknowledgments
this&ObjectPrototypes
Foreword
Preface
thisOrThat?
thisAllMakesSenseNow!
Objects
Mixing(Up)"Class"Objects
Prototypes
BehaviorDelegation
ES6class
1
-
1.4.10
1.5
1.5.1
1.5.2
1.5.3
1.5.4
1.5.5
1.5.6
1.5.7
1.5.8
1.6
1.6.1
1.6.2
1.6.3
1.6.4
1.6.5
1.6.6
1.6.7
1.6.8
1.6.9
1.6.10
1.7
1.7.1
1.7.2
1.7.3
1.7.4
1.7.5
1.7.6
1.7.7
1.7.8
1.7.9
1.7.10
1.8
Acknowledgments
Types&Grammar
Foreword
Preface
Types
Values
Natives
Coercion
Grammar
MixedEnvironmentJavaScript
Async&Performance
Foreword
Preface
Asynchrony:Now&Later
Callbacks
Promises
Generators
ProgramPerformance
Benchmarking&Tuning
asynquenceLibrary
AdvancedAsyncPatterns
ES6&Beyond
Foreword
Preface
ES?Now&Future
Syntax
Organization
AsyncFlowControl
Collections
APIAdditions
MetaProgramming
BeyondES6
Acknowledgments
2
-
3
-
YouDon'tKnowJS(bookseries)ThisisaseriesofbooksdivingdeepintothecoremechanismsoftheJavaScriptlanguage.Thefirsteditionoftheseriesisnowcomplete.
Introduction
4
-
up&going
5
-
Whatwasthelastnewthingyoulearned?
Perhapsitwasaforeignlanguage,likeItalianorGerman.Ormaybeitwasagraphicseditor,likePhotoshop.Oracookingtechniqueorwoodworkingoranexerciseroutine.Iwantyoutorememberthatfeelingwhenyoufinallygotit:thelightbulbmoment.Whenthingswentfromblurrytocrystalclear,asyoumasteredthetablesaworunderstoodthedifferencebetweenmasculineandfemininenounsinFrench.Howdiditfeel?Prettyamazing,right?
NowIwantyoutotravelbackalittlebitfurtherinyourmemorytorightbeforeyoulearnedyournewskill.Howdidthatfeel?Probablyslightlyintimidatingandmaybealittlebitfrustrating,right?Atonepoint,wealldidnotknowthethingsthatweknownowandthat’stotallyOK;weallstartsomewhere.Learningnewmaterialisanexcitingadventure,especiallyifyouarelookingtolearnthesubjectefficiently.
Iteachalotofbeginnercodingclasses.ThestudentswhotakemyclasseshaveoftentriedteachingthemselvessubjectslikeHTMLorJavaScriptbyreadingblogpostsorcopyingandpastingcode,buttheyhaven’tbeenabletotrulymasterthematerialthatwillallowthemtocodetheirdesiredoutcome.Andbecausetheydon’ttrulygrasptheinsandoutsofcertaincodingtopics,theycan’twritepowerfulcodeordebugtheirownwork,astheydon’treallyunderstandwhatishappening.
Ialwaysbelieveinteachingmyclassestheproperway,meaningIteachwebstandards,semanticmarkup,well-commentedcode,andotherbestpractices.Icoverthesubjectinathoroughmannertoexplainthehowsandwhys,withoutjusttossingoutcodetocopyandpaste.Whenyoustrivetocomprehendyourcode,youcreatebetterworkandbecomebetteratwhatyoudo.Thecodeisn’tjustyourjobanymore,it’syourcraft.ThisiswhyIloveUp&Going.KyletakesusonadeepdivethroughsyntaxandterminologytogiveagreatintroductiontoJavaScriptwithoutcuttingcorners.Thisbookdoesn’tskimoverthesurface,butreallyallowsustogenuinelyunderstandtheconceptswewillbewriting.
Becauseit’snotenoughtobeabletoduplicatejQuerysnippetsintoyourwebsite,thesamewayit’snotenoughtolearnhowtoopen,close,andsaveadocumentinPhotoshop.Sure,onceIlearnafewbasicsabouttheprogramIcouldcreateandshareadesignImade.Butwithoutlegitimatelyknowingthetoolsandwhatisbehindthem,howcanIdefineagrid,orcraftalegibletypesystem,oroptimizegraphicsforwebuse.ThesamegoesforJavaScript.Withoutknowinghowloopswork,orhowtodefinevariables,orwhatscopeis,wewon’tbewritingthebestcodewecan.Wedon’twanttosettleforanythingless--thisis,afterall,ourcraft.
ThemoreyouareexposedtoJavaScript,thecleareritbecomes.Wordslikeclosures,objects,andmethodsmightseemoutofreachtoyounow,butthisbookwillhelpthosetermscomeintoclarity.Iwantyoutokeepthosetwofeelingsofbeforeandafteryoulearn
Foreword
6
-
somethinginmindasyoubeginthisbook.Itmightseemdaunting,butyou’vepickedupthisbookbecauseyouarestartinganawesomejourneytohoneyourknowledge.Up&Goingisthestartofourpathtounderstandingprogramming.Enjoythelightbulbmoments!
JennLukasjennlukas.com,@jennlukasFront-endconsultant
Foreword
7
http://jennlukas.com/https://twitter.com/jennlukas
-
I'msureyounoticed,but"JS"inthebookseriestitleisnotanabbreviationforwordsusedtocurseaboutJavaScript,thoughcursingatthelanguage'squirksissomethingwecanprobablyallidentifywith!
Fromtheearliestdaysoftheweb,JavaScripthasbeenafoundationaltechnologythatdrivesinteractiveexperiencearoundthecontentweconsume.Whileflickeringmousetrailsandannoyingpop-uppromptsmaybewhereJavaScriptstarted,nearly2decadeslater,thetechnologyandcapabilityofJavaScripthasgrownmanyordersofmagnitude,andfewdoubtitsimportanceattheheartoftheworld'smostwidelyavailablesoftwareplatform:theweb.
Butasalanguage,ithasperpetuallybeenatargetforagreatdealofcriticism,owingpartlytoitsheritagebutevenmoretoitsdesignphilosophy.Eventhenameevokes,asBrendanEichonceputit,"dumbkidbrother"statusnexttoitsmorematureolderbrother"Java".Butthenameismerelyanaccidentofpoliticsandmarketing.Thetwolanguagesarevastlydifferentinmanyimportantways."JavaScript"isasrelatedto"Java"as"Carnival"isto"Car".
BecauseJavaScriptborrowsconceptsandsyntaxidiomsfromseverallanguages,includingproudC-styleproceduralrootsaswellassubtle,lessobviousScheme/Lisp-stylefunctionalroots,itisexceedinglyapproachabletoabroadaudienceofdevelopers,eventhosewithjustlittletonoprogrammingexperience.The"HelloWorld"ofJavaScriptissosimplethatthelanguageisinvitingandeasytogetcomfortablewithinearlyexposure.
WhileJavaScriptisperhapsoneoftheeasiestlanguagestogetupandrunningwith,itseccentricitiesmakesolidmasteryofthelanguageavastlylesscommonoccurrencethaninmanyotherlanguages.Whereittakesaprettyin-depthknowledgeofalanguagelikeCorC++towriteafull-scaleprogram,full-scaleproductionJavaScriptcan,andoftendoes,barelyscratchthesurfaceofwhatthelanguagecando.
Sophisticatedconceptswhicharedeeplyrootedintothelanguagetendinsteadtosurfacethemselvesinseeminglysimplisticways,suchaspassingaroundfunctionsascallbacks,whichencouragestheJavaScriptdevelopertojustusethelanguageas-isandnotworrytoomuchaboutwhat'sgoingonunderthehood.
Itissimultaneouslyasimple,easy-to-uselanguagethathasbroadappeal,andacomplexandnuancedcollectionoflanguagemechanicswhichwithoutcarefulstudywilleludetrueunderstandingevenforthemostseasonedofJavaScriptdevelopers.
ThereinliestheparadoxofJavaScript,theAchilles'Heelofthelanguage,thechallengewearepresentlyaddressing.BecauseJavaScriptcanbeusedwithoutunderstanding,theunderstandingofthelanguageisoftenneverattained.
Mission
Preface
8
-
IfateverypointthatyouencounterasurpriseorfrustrationinJavaScript,yourresponseistoaddittotheblacklist,assomeareaccustomedtodoing,yousoonwillberelegatedtoahollowshelloftherichnessofJavaScript.
Whilethissubsethasbeenfamouslydubbed"TheGoodParts",Iwouldimploreyou,dearreader,toinsteadconsideritthe"TheEasyParts","TheSafeParts",oreven"TheIncompleteParts".
ThisYouDon'tKnowJavaScriptbookseriesoffersacontrarychallenge:learnanddeeplyunderstandallofJavaScript,evenandespecially"TheToughParts".
Here,weaddressheadonthetendencyofJSdeveloperstolearn"justenough"togetby,withouteverforcingthemselvestolearnexactlyhowandwhythelanguagebehavesthewayitdoes.Furthermore,weeschewthecommonadvicetoretreatwhentheroadgetsrough.
Iamnotcontent,norshouldyoube,atstoppingoncesomethingjustworks,andnotreallyknowingwhy.Igentlychallengeyoutojourneydownthatbumpy"roadlesstraveled"andembraceallthatJavaScriptisandcando.Withthatknowledge,notechnique,noframework,nopopularbuzzwordacronymoftheweek,willbebeyondyourunderstanding.
Thesebookseachtakeonspecificcorepartsofthelanguagewhicharemostcommonlymisunderstoodorunder-understood,anddiveverydeepandexhaustivelyintothem.Youshouldcomeawayfromreadingwithafirmconfidenceinyourunderstanding,notjustofthetheoretical,butthepractical"whatyouneedtoknow"bits.
TheJavaScriptyouknowrightnowisprobablypartshandeddowntoyoubyotherswho'vebeenburnedbyincompleteunderstanding.ThatJavaScriptisbutashadowofthetruelanguage.Youdon'treallyknowJavaScript,yet,butifyoudigintothisseries,youwill.Readon,myfriends.JavaScriptawaitsyou.
SummaryJavaScriptisawesome.It'seasytolearnpartially,andmuchhardertolearncompletely(orevensufficiently).Whendevelopersencounterconfusion,theyusuallyblamethelanguageinsteadoftheirlackofunderstanding.Thesebooksaimtofixthat,inspiringastrongappreciationforthelanguageyoucannow,andshould,deeplyknow.
Note:Manyoftheexamplesinthisbookassumemodern(andfuture-reaching)JavaScriptengineenvironments,suchasES6.Somecodemaynotworkasdescribedifruninolder(pre-ES6)engines.
Preface
9
-
Preface
10
-
WelcometotheYouDon'tKnowJS(YDKJS)series.
Up&Goingisanintroductiontoseveralbasicconceptsofprogramming--ofcourseweleantowardJavaScript(oftenabbreviatedJS)specifically--andhowtoapproachandunderstandtherestofthetitlesinthisseries.Especiallyifyou'rejustgettingintoprogrammingand/orJavaScript,thisbookwillbrieflyexplorewhatyouneedtogetupandgoing.
Thisbookstartsoffexplainingthebasicprinciplesofprogrammingataveryhighlevel.It'smostlyintendedifyouarestartingYDKJSwithlittletonopriorprogrammingexperience,andarelookingtothesebookstohelpgetyoustartedalongapathtounderstandingprogrammingthroughthelensofJavaScript.
Chapter1shouldbeapproachedasaquickoverviewofthethingsyou'llwanttolearnmoreaboutandpracticetogetintoprogramming.Therearealsomanyotherfantasticprogrammingintroductionresourcesthatcanhelpyoudigintothesetopicsfurther,andIencourageyoutolearnfromtheminadditiontothischapter.
Onceyoufeelcomfortablewithgeneralprogrammingbasics,Chapter2willhelpguideyoutoafamiliaritywithJavaScript'sflavorofprogramming.Chapter2introduceswhatJavaScriptisabout,butagain,it'snotacomprehensiveguide--that'swhattherestoftheYDKJSbooksarefor!
Ifyou'realreadyfairlycomfortablewithJavaScript,firstcheckoutChapter3asabriefglimpseofwhattoexpectfromYDKJS,thenjumprightin!
CodeLet'sstartfromthebeginning.
Aprogram,oftenreferredtoassourcecodeorjustcode,isasetofspecialinstructionstotellthecomputerwhattaskstoperform.Usuallycodeissavedinatextfile,althoughwithJavaScriptyoucanalsotypecodedirectlyintoadeveloperconsoleinabrowser,whichwe'llcovershortly.
Therulesforvalidformatandcombinationsofinstructionsiscalledacomputerlanguage,sometimesreferredtoasitssyntax,muchthesameasEnglishtellsyouhowtospellwordsandhowtocreatevalidsentencesusingwordsandpunctuation.
Statements
Inacomputerlanguage,agroupofwords,numbers,andoperatorsthatperformsaspecifictaskisastatement.InJavaScript,astatementmightlookasfollows:
IntoProgramming
11
-
a=b*2;
Thecharactersaandbarecalledvariables(see"Variables"),whicharelikesimpleboxesyoucanstoreanyofyourstuffin.Inprograms,variablesholdvalues(likethenumber42)tobeusedbytheprogram.Thinkofthemassymbolicplaceholdersforthevaluesthemselves.
Bycontrast,the2isjustavalueitself,calledaliteralvalue,becauseitstandsalonewithoutbeingstoredinavariable.
The=and*charactersareoperators(see"Operators")--theyperformactionswiththevaluesandvariablessuchasassignmentandmathematicmultiplication.
MoststatementsinJavaScriptconcludewithasemicolon(;)attheend.
Thestatementa=b*2;tellsthecomputer,roughly,togetthecurrentvaluestoredinthevariableb,multiplythatvalueby2,thenstoretheresultbackintoanothervariablewecalla.
Programsarejustcollectionsofmanysuchstatements,whichtogetherdescribeallthestepsthatittakestoperformyourprogram'spurpose.
Expressions
Statementsaremadeupofoneormoreexpressions.Anexpressionisanyreferencetoavariableorvalue,orasetofvariable(s)andvalue(s)combinedwithoperators.
Forexample:
a=b*2;
Thisstatementhasfourexpressionsinit:
2isaliteralvalueexpressionbisavariableexpression,whichmeanstoretrieveitscurrentvalueb*2isanarithmeticexpression,whichmeanstodothemultiplicationa=b*2isanassignmentexpression,whichmeanstoassigntheresultoftheb*2expressiontothevariablea(moreonassignmentslater)
Ageneralexpressionthatstandsaloneisalsocalledanexpressionstatement,suchasthefollowing:
b*2;
IntoProgramming
12
-
Thisflavorofexpressionstatementisnotverycommonoruseful,asgenerallyitwouldn'thaveanyeffectontherunningoftheprogram--itwouldretrievethevalueofbandmultiplyitby2,butthenwouldn'tdoanythingwiththatresult.
Amorecommonexpressionstatementisacallexpressionstatement(see"Functions"),astheentirestatementisthefunctioncallexpressionitself:
alert(a);
ExecutingaProgram
Howdothosecollectionsofprogrammingstatementstellthecomputerwhattodo?Theprogramneedstobeexecuted,alsoreferredtoasrunningtheprogram.
Statementslikea=b*2arehelpfulfordeveloperswhenreadingandwriting,butarenotactuallyinaformthecomputercandirectlyunderstand.Soaspecialutilityonthecomputer(eitheraninterpreteroracompiler)isusedtotranslatethecodeyouwriteintocommandsacomputercanunderstand.
Forsomecomputerlanguages,thistranslationofcommandsistypicallydonefromtoptobottom,linebyline,everytimetheprogramisrun,whichisusuallycalledinterpretingthecode.
Forotherlanguages,thetranslationisdoneaheadoftime,calledcompilingthecode,sowhentheprogramrunslater,what'srunningisactuallythealreadycompiledcomputerinstructionsreadytogo.
It'stypicallyassertedthatJavaScriptisinterpreted,becauseyourJavaScriptsourcecodeisprocessedeachtimeit'srun.Butthat'snotentirelyaccurate.TheJavaScriptengineactuallycompilestheprogramontheflyandthenimmediatelyrunsthecompiledcode.
Note:FormoreinformationonJavaScriptcompiling,seethefirsttwochaptersoftheScope&Closurestitleofthisseries.
TryItYourselfThischapterisgoingtointroduceeachprogrammingconceptwithsimplesnippetsofcode,allwritteninJavaScript(obviously!).
Itcannotbeemphasizedenough:whileyougothroughthischapter--andyoumayneedtospendthetimetogooveritseveraltimes--youshouldpracticeeachoftheseconceptsbytypingthecodeyourself.Theeasiestwaytodothatistoopenupthedevelopertoolsconsoleinyournearestbrowser(Firefox,Chrome,IE,etc.).
IntoProgramming
13
-
Tip:Typically,youcanlaunchthedeveloperconsolewithakeyboardshortcutorfromamenuitem.Formoredetailedinformationaboutlaunchingandusingtheconsoleinyourfavoritebrowser,see"MasteringTheDeveloperToolsConsole"(http://blog.teamtreehouse.com/mastering-developer-tools-console).Totypemultiplelinesintotheconsoleatonce,use+tomovetothenextnewline.Onceyouhitbyitself,theconsolewillruneverythingyou'vejusttyped.
Let'sgetfamiliarwiththeprocessofrunningcodeintheconsole.First,Isuggestopeningupanemptytabinyourbrowser.Iprefertodothisbytypingabout:blankintotheaddressbar.Then,makesureyourdeveloperconsoleisopen,aswejustmentioned.
Now,typethiscodeandseehowitruns:
a=21;
b=a*2;
console.log(b);
TypingtheprecedingcodeintotheconsoleinChromeshouldproducesomethinglikethefollowing:
IntoProgramming
14
http://blog.teamtreehouse.com/mastering-developer-tools-console
-
Goon,tryit.Thebestwaytolearnprogrammingistostartcoding!
Output
Inthepreviouscodesnippet,weusedconsole.log(..).Briefly,let'slookatwhatthatlineofcodeisallabout.
Youmayhaveguessed,butthat'sexactlyhowweprinttext(akaoutputtotheuser)inthedeveloperconsole.Therearetwocharacteristicsofthatstatementthatweshouldexplain.
First,thelog(b)partisreferredtoasafunctioncall(see"Functions").What'shappeningiswe'rehandingthebvariabletothatfunction,whichasksittotakethevalueofbandprintittotheconsole.
Second,theconsole.partisanobjectreferencewherethelog(..)functionislocated.WecoverobjectsandtheirpropertiesinmoredetailinChapter2.
Anotherwayofcreatingoutputthatyoucanseeistorunanalert(..)statement.Forexample:
alert(b);
Ifyourunthat,you'llnoticethatinsteadofprintingtheoutputtotheconsole,itshowsapopup"OK"boxwiththecontentsofthebvariable.However,usingconsole.log(..)isgenerallygoingtomakelearningaboutcodingandrunningyourprogramsintheconsoleeasierthanusingalert(..),becauseyoucanoutputmanyvaluesatoncewithoutinterruptingthebrowserinterface.
Forthisbook,we'lluseconsole.log(..)foroutput.
Input
Whilewe'rediscussingoutput,youmayalsowonderaboutinput(i.e.,receivinginformationfromtheuser).
ThemostcommonwaythathappensisfortheHTMLpagetoshowformelements(liketextboxes)toauserthattheycantypeinto,andthenusingJStoreadthosevaluesintoyourprogram'svariables.
Butthere'saneasierwaytogetinputforsimplelearninganddemonstrationpurposessuchaswhatyou'llbedoingthroughoutthisbook.Usetheprompt(..)function:
IntoProgramming
15
-
age=prompt("Pleasetellmeyourage:");
console.log(age);
Asyoumayhaveguessed,themessageyoupasstoprompt(..)--inthiscase,"Pleasetellmeyourage:"--isprintedintothepopup.
Thisshouldlooksimilartothefollowing:
Onceyousubmittheinputtextbyclicking"OK,"you'llobservethatthevalueyoutypedisstoredintheagevariable,whichwethenoutputwithconsole.log(..):
IntoProgramming
16
-
Tokeepthingssimplewhilewe'relearningbasicprogrammingconcepts,theexamplesinthisbookwillnotrequireinput.Butnowthatyou'veseenhowtouseprompt(..),ifyouwanttochallengeyourselfyoucantrytouseinputinyourexplorationsoftheexamples.
OperatorsOperatorsarehowweperformactionsonvariablesandvalues.We'vealreadyseentwoJavaScriptoperators,the=andthe*.
The*operatorperformsmathematicmultiplication.Simpleenough,right?
The=equalsoperatorisusedforassignment--wefirstcalculatethevalueontheright-handside(sourcevalue)ofthe=andthenputitintothevariablethatwespecifyontheleft-handside(targetvariable).
Warning:Thismayseemlikeastrangereverseordertospecifyassignment.Insteadofa=42,somemightprefertofliptheordersothesourcevalueisontheleftandthetargetvariableisontheright,like42->a(thisisnotvalidJavaScript!).Unfortunately,thea=
IntoProgramming
17
-
42orderedform,andsimilarvariations,isquiteprevalentinmodernprogramminglanguages.Ifitfeelsunnatural,justspendsometimerehearsingthatorderinginyourmindtogetaccustomedtoit.
Consider:
a=2;b=a+1;
Here,weassignthe2valuetotheavariable.Then,wegetthevalueoftheavariable(still2),add1toitresultinginthevalue3,thenstorethatvalueinthebvariable.
Whilenottechnicallyanoperator,you'llneedthekeywordvarineveryprogram,asit'stheprimarywayyoudeclare(akacreate)variables(see"Variables").
Youshouldalwaysdeclarethevariablebynamebeforeyouuseit.Butyouonlyneedtodeclareavariableonceforeachscope(see"Scope");itcanbeusedasmanytimesafterthatasneeded.Forexample:
vara=20;
a=a+1;a=a*2;
console.log(a);//42
HerearesomeofthemostcommonoperatorsinJavaScript:
Assignment:=asina=2.Math:+(addition),-(subtraction),*(multiplication),and/(division),asina*3.CompoundAssignment:+=,-=,*=,and/=arecompoundoperatorsthatcombineamathoperationwithassignment,asina+=2(sameasa=a+2).Increment/Decrement:++(increment),--(decrement),asina++(similartoa=a+1).ObjectPropertyAccess:.asinconsole.log().
Objectsarevaluesthatholdothervaluesatspecificnamedlocationscalledproperties.obj.ameansanobjectvaluecalledobjwithapropertyofthenamea.Propertiescanalternativelybeaccessedasobj["a"].SeeChapter2.
Equality:==(loose-equals),===(strict-equals),!=(loosenot-equals),!==(strictnot-equals),asina==b.
See"Values&Types"andChapter2.
IntoProgramming
18
-
Comparison:<(lessthan),>(greaterthan),=(greaterthanorloose-equals),asina
-
etc.).
Consider:
"Iamastring";'Iamalsoastring';
42;
true;false;
Beyondstring/number/booleanvaluetypes,it'scommonforprogramminglanguagestoprovidearrays,objects,functions,andmore.We'llcovermuchmoreaboutvaluesandtypesthroughoutthischapterandthenext.
ConvertingBetweenTypes
Ifyouhaveanumberbutneedtoprintitonthescreen,youneedtoconvertthevaluetoastring,andinJavaScriptthisconversioniscalled"coercion."Similarly,ifsomeoneentersaseriesofnumericcharactersintoaformonanecommercepage,that'sastring,butifyouneedtothenusethatvaluetodomathoperations,youneedtocoerceittoanumber.
JavaScriptprovidesseveraldifferentfacilitiesforforciblycoercingbetweentypes.Forexample:
vara="42";varb=Number(a);
console.log(a);//"42"console.log(b);//42
UsingNumber(..)(abuilt-infunction)asshownisanexplicitcoercionfromanyothertypetothenumbertype.Thatshouldbeprettystraightforward.
Butacontroversialtopiciswhathappenswhenyoutrytocomparetwovaluesthatarenotalreadyofthesametype,whichwouldrequireimplicitcoercion.
Whencomparingthestring"99.99"tothenumber99.99,mostpeoplewouldagreetheyareequivalent.Butthey'renotexactlythesame,arethey?It'sthesamevalueintwodifferentrepresentations,twodifferenttypes.Youcouldsaythey're"looselyequal,"couldn'tyou?
Tohelpyououtinthesecommonsituations,JavaScriptwillsometimeskickinandimplicitlycoercevaluestothematchingtypes.
IntoProgramming
20
-
Soifyouusethe==looseequalsoperatortomakethecomparison"99.99"==99.99,JavaScriptwillconverttheleft-handside"99.99"toitsnumberequivalent99.99.Thecomparisonthenbecomes99.99==99.99,whichisofcoursetrue.
Whiledesignedtohelpyou,implicitcoercioncancreateconfusionifyouhaven'ttakenthetimetolearntherulesthatgovernitsbehavior.MostJSdevelopersneverhave,sothecommonfeelingisthatimplicitcoercionisconfusingandharmsprogramswithunexpectedbugs,andshouldthusbeavoided.It'sevensometimescalledaflawinthedesignofthelanguage.
However,implicitcoercionisamechanismthatcanbelearned,andmoreovershouldbelearnedbyanyonewishingtotakeJavaScriptprogrammingseriously.Notonlyisitnotconfusingonceyoulearntherules,itcanactuallymakeyourprogramsbetter!Theeffortiswellworthit.
Note:Formoreinformationoncoercion,seeChapter2ofthistitleandChapter4oftheTypes&Grammartitleofthisseries.
CodeCommentsThephonestoreemployeemightjotdownsomenotesonthefeaturesofanewlyreleasedphoneoronthenewplanshercompanyoffers.Thesenotesareonlyfortheemployee--they'renotforcustomerstoread.Nevertheless,thesenoteshelptheemployeedoherjobbetterbydocumentingthehowsandwhysofwhatsheshouldtellcustomers.
Oneofthemostimportantlessonsyoucanlearnaboutwritingcodeisthatit'snotjustforthecomputer.Codeiseverybitasmuch,ifnotmore,forthedeveloperasitisforthecompiler.
Yourcomputeronlycaresaboutmachinecode,aseriesofbinary0sand1s,thatcomesfromcompilation.There'sanearlyinfinitenumberofprogramsyoucouldwritethatyieldthesameseriesof0sand1s.Thechoicesyoumakeabouthowtowriteyourprogrammatter--notonlytoyou,buttoyourotherteammembersandeventoyourfutureself.
Youshouldstrivenotjusttowriteprogramsthatworkcorrectly,butprogramsthatmakesensewhenexamined.Youcangoalongwayinthateffortbychoosinggoodnamesforyourvariables(see"Variables")andfunctions(see"Functions").
Butanotherimportantpartiscodecomments.Thesearebitsoftextinyourprogramthatareinsertedpurelytoexplainthingstoahuman.Theinterpreter/compilerwillalwaysignorethesecomments.
Therearelotsofopinionsonwhatmakeswell-commentedcode;wecan'treallydefineabsoluteuniversalrules.Butsomeobservationsandguidelinesarequiteuseful:
IntoProgramming
21
-
Codewithoutcommentsissuboptimal.Toomanycomments(oneperline,forexample)isprobablyasignofpoorlywrittencode.Commentsshouldexplainwhy,notwhat.Theycanoptionallyexplainhowifthat'sparticularlyconfusing.
InJavaScript,therearetwotypesofcommentspossible:asingle-linecommentandamultilinecomment.
Consider:
//Thisisasingle-linecomment
/*Butthisisamultilinecomment.*/
The//single-linecommentisappropriateifyou'regoingtoputacommentrightaboveasinglestatement,orevenattheendofaline.Everythingonthelineafterthe//istreatedasthecomment(andthusignoredbythecompiler),allthewaytotheendoftheline.There'snorestrictiontowhatcanappearinsideasingle-linecomment.
Consider:
vara=42;//42isthemeaningoflife
The/*..*/multilinecommentisappropriateifyouhaveseverallinesworthofexplanationtomakeinyourcomment.
Here'sacommonusageofmultilinecomments:
/*Thefollowingvalueisusedbecauseithasbeenshownthatitanswerseveryquestionintheuniverse.*/vara=42;
Itcanalsoappearanywhereonaline,eveninthemiddleofaline,becausethe*/endsit.Forexample:
vara=/*arbitraryvalue*/42;
console.log(a);//42
IntoProgramming
22
-
Theonlythingthatcannotappearinsideamultilinecommentisa*/,becausethatwouldbeinterpretedtoendthecomment.
Youwilldefinitelywanttobeginyourlearningofprogrammingbystartingoffwiththehabitofcommentingcode.Throughouttherestofthischapter,you'llseeIusecommentstoexplainthings,sodothesameinyourownpractice.Trustme,everyonewhoreadsyourcodewillthankyou!
VariablesMostusefulprogramsneedtotrackavalueasitchangesoverthecourseoftheprogram,undergoingdifferentoperationsascalledforbyyourprogram'sintendedtasks.
Theeasiestwaytogoaboutthatinyourprogramistoassignavaluetoasymboliccontainer,calledavariable--socalledbecausethevalueinthiscontainercanvaryovertimeasneeded.
Insomeprogramminglanguages,youdeclareavariable(container)toholdaspecifictypeofvalue,suchasnumberorstring.Statictyping,otherwiseknownastypeenforcement,istypicallycitedasabenefitforprogramcorrectnessbypreventingunintendedvalueconversions.
Otherlanguagesemphasizetypesforvaluesinsteadofvariables.Weaktyping,otherwiseknownasdynamictyping,allowsavariabletoholdanytypeofvalueatanytime.It'stypicallycitedasabenefitforprogramflexibilitybyallowingasinglevariabletorepresentavaluenomatterwhattypeformthatvaluemaytakeatanygivenmomentintheprogram'slogicflow.
JavaScriptusesthelatterapproach,dynamictyping,meaningvariablescanholdvaluesofanytypewithoutanytypeenforcement.
Asmentionedearlier,wedeclareavariableusingthevarstatement--noticethere'snoothertypeinformationinthedeclaration.Considerthissimpleprogram:
IntoProgramming
23
-
varamount=99.99;
amount=amount*2;
console.log(amount);//199.98
//convert`amount`toastring,and//add"$"onthebeginningamount="$"+String(amount);
console.log(amount);//"$199.98"
Theamountvariablestartsoutholdingthenumber99.99,andthenholdsthenumberresultofamount*2,whichis199.98.
Thefirstconsole.log(..)commandhastoimplicitlycoercethatnumbervaluetoastringtoprintitout.
Thenthestatementamount="$"+String(amount)explicitlycoercesthe199.98valuetoastringandaddsa"$"charactertothebeginning.Atthispoint,amountnowholdsthestringvalue"$199.98",sothesecondconsole.log(..)statementdoesn'tneedtodoanycoerciontoprintitout.
JavaScriptdeveloperswillnotetheflexibilityofusingtheamountvariableforeachofthe99.99,199.98,andthe"$199.98"values.Static-typingenthusiastswouldpreferaseparatevariablelikeamountStrtoholdthefinal"$199.98"representationofthevalue,becauseit'sadifferenttype.
Eitherway,you'llnotethatamountholdsarunningvaluethatchangesoverthecourseoftheprogram,illustratingtheprimarypurposeofvariables:managingprogramstate.
Inotherwords,stateistrackingthechangestovaluesasyourprogramruns.
Anothercommonusageofvariablesisforcentralizingvaluesetting.Thisismoretypicallycalledconstants,whenyoudeclareavariablewithavalueandintendforthatvaluetonotchangethroughouttheprogram.
Youdeclaretheseconstants,oftenatthetopofaprogram,sothatit'sconvenientforyoutohaveoneplacetogotoalteravalueifyouneedto.Byconvention,JavaScriptvariablesasconstantsareusuallycapitalized,withunderscores_betweenmultiplewords.
Here'sasillyexample:
IntoProgramming
24
-
varTAX_RATE=0.08;//8%salestax
varamount=99.99;
amount=amount*2;
amount=amount+(amount*TAX_RATE);
console.log(amount);//215.9784console.log(amount.toFixed(2));//"215.98"
Note:Similartohowconsole.log(..)isafunctionlog(..)accessedasanobjectpropertyontheconsolevalue,toFixed(..)hereisafunctionthatcanbeaccessedonnumbervalues.JavaScriptnumbersaren'tautomaticallyformattedfordollars--theenginedoesn'tknowwhatyourintentisandthere'snotypeforcurrency.toFixed(..)letsusspecifyhowmanydecimalplaceswe'dlikethenumberroundedto,anditproducesthestringasnecessary.
TheTAX_RATEvariableisonlyconstantbyconvention--there'snothingspecialinthisprogramthatpreventsitfrombeingchanged.Butifthecityraisesthesalestaxrateto9%,wecanstilleasilyupdateourprogrambysettingtheTAX_RATEassignedvalueto0.09inoneplace,insteadoffindingmanyoccurrencesofthevalue0.08strewnthroughouttheprogramandupdatingallofthem.
ThenewestversionofJavaScriptatthetimeofthiswriting(commonlycalled"ES6")includesanewwaytodeclareconstants,byusingconstinsteadofvar:
//asofES6:constTAX_RATE=0.08;
varamount=99.99;
//..
Constantsareusefuljustlikevariableswithunchangedvalues,exceptthatconstantsalsopreventaccidentallychangingvaluesomewhereelseaftertheinitialsetting.IfyoutriedtoassignanydifferentvaluetoTAX_RATEafterthatfirstdeclaration,yourprogramwouldrejectthechange(andinstrictmode,failwithanerror--see"StrictMode"inChapter2).
Bytheway,thatkindof"protection"againstmistakesissimilartothestatic-typingtypeenforcement,soyoucanseewhystatictypesinotherlanguagescanbeattractive!
Note:Formoreinformationabouthowdifferentvaluesinvariablescanbeusedinyourprograms,seetheTypes&Grammartitleofthisseries.
IntoProgramming
25
-
BlocksThephonestoreemployeemustgothroughaseriesofstepstocompletethecheckoutasyoubuyyournewphone.
Similarly,incodeweoftenneedtogroupaseriesofstatementstogether,whichweoftencallablock.InJavaScript,ablockisdefinedbywrappingoneormorestatementsinsideacurly-bracepair{..}.Consider:
varamount=99.99;
//ageneralblock{amount=amount*2;console.log(amount);//199.98}
Thiskindofstandalone{..}generalblockisvalid,butisn'tascommonlyseeninJSprograms.Typically,blocksareattachedtosomeothercontrolstatement,suchasanifstatement(see"Conditionals")oraloop(see"Loops").Forexample:
varamount=99.99;
//isamountbigenough?if(amount>10){//
-
Therearequiteafewwayswecanexpressconditionals(akadecisions)inourprograms.
Themostcommononeistheifstatement.Essentially,you'resaying,"Ifthisconditionistrue,dothefollowing...".Forexample:
varbank_balance=302.13;varamount=99.99;
if(amount<bank_balance){console.log("Iwanttobuythisphone!");}
Theifstatementrequiresanexpressioninbetweentheparentheses()thatcanbetreatedaseithertrueorfalse.Inthisprogram,weprovidedtheexpressionamount<bank_balance,whichindeedwilleitherevaluatetotrueorfalsedependingontheamountinthebank_balancevariable.
Youcanevenprovideanalternativeiftheconditionisn'ttrue,calledanelseclause.Consider:
constACCESSORY_PRICE=9.99;
varbank_balance=302.13;varamount=99.99;
amount=amount*2;
//canweaffordtheextrapurchase?if(amount<bank_balance){console.log("I'lltaketheaccessory!");amount=amount+ACCESSORY_PRICE;}//otherwise:else{console.log("No,thanks.");}
Here,ifamount<bank_balanceistrue,we'llprintout"I'lltaketheaccessory!"andaddthe9.99toouramountvariable.Otherwise,theelseclausesayswe'lljustpolitelyrespondwith"No,thanks."andleaveamountunchanged.
Aswediscussedin"Values&Types"earlier,valuesthataren'talreadyofanexpectedtypeareoftencoercedtothattype.Theifstatementexpectsaboolean,butifyoupassitsomethingthat'snotalreadyboolean,coercionwilloccur.
IntoProgramming
27
-
JavaScriptdefinesalistofspecificvaluesthatareconsidered"falsy"becausewhencoercedtoaboolean,theybecomefalse--theseincludevalueslike0and"".Anyothervaluenotonthe"falsy"listisautomatically"truthy"--whencoercedtoabooleantheybecometrue.Truthyvaluesincludethingslike99.99and"free".See"Truthy&Falsy"inChapter2formoreinformation.
Conditionalsexistinotherformsbesidestheif.Forexample,theswitchstatementcanbeusedasashorthandforaseriesofif..elsestatements(seeChapter2).Loops(see"Loops")useaconditionaltodetermineiftheloopshouldkeepgoingorstop.
Note:Fordeeperinformationaboutthecoercionsthatcanoccurimplicitlyinthetestexpressionsofconditionals,seeChapter4oftheTypes&Grammartitleofthisseries.
LoopsDuringbusytimes,there'sawaitinglistforcustomerswhoneedtospeaktothephonestoreemployee.Whilethere'sstillpeopleonthatlist,shejustneedstokeepservingthenextcustomer.
Repeatingasetofactionsuntilacertainconditionfails--inotherwords,repeatingonlywhiletheconditionholds--isthejobofprogrammingloops;loopscantakedifferentforms,buttheyallsatisfythisbasicbehavior.
Aloopincludesthetestconditionaswellasablock(typicallyas{..}).Eachtimetheloopblockexecutes,that'scalledaniteration.
Forexample,thewhileloopandthedo..whileloopformsillustratetheconceptofrepeatingablockofstatementsuntilaconditionnolongerevaluatestotrue:
IntoProgramming
28
-
while(numOfCustomers>0){console.log("HowmayIhelpyou?");
//helpthecustomer...
numOfCustomers=numOfCustomers-1;}
//versus:
do{console.log("HowmayIhelpyou?");
//helpthecustomer...
numOfCustomers=numOfCustomers-1;}while(numOfCustomers>0);
Theonlypracticaldifferencebetweentheseloopsiswhethertheconditionalistestedbeforethefirstiteration(while)orafterthefirstiteration(do..while).
Ineitherform,iftheconditionaltestsasfalse,thenextiterationwillnotrun.Thatmeansiftheconditionisinitiallyfalse,awhileloopwillneverrun,butado..whileloopwillrunjustthefirsttime.
Sometimesyouareloopingfortheintendedpurposeofcountingacertainsetofnumbers,likefrom0to9(tennumbers).Youcandothatbysettingaloopiterationvariablelikeiatvalue0andincrementingitby1eachiteration.
Warning:Foravarietyofhistoricalreasons,programminglanguagesalmostalwayscountthingsinazero-basedfashion,meaningstartingwith0insteadof1.Ifyou'renotfamiliarwiththatmodeofthinking,itcanbequiteconfusingatfirst.Takesometimetopracticecountingstartingwith0tobecomemorecomfortablewithit!
Theconditionalistestedoneachiteration,muchasifthereisanimpliedifstatementinsidetheloop.
WecanuseJavaScript'sbreakstatementtostopaloop.Also,wecanobservethatit'sawfullyeasytocreatealoopthatwouldotherwiserunforeverwithoutabreakingmechanism.
Let'sillustrate:
IntoProgramming
29
-
vari=0;
//a`while..true`loopwouldrunforever,right?while(true){//stoptheloop?if((i
-
Similarly,yourprogramwillalmostcertainlywanttobreakupthecode'stasksintoreusablepieces,insteadofrepeatedlyrepeatingyourselfrepetitiously(punintended!).Thewaytodothisistodefineafunction.
Afunctionisgenerallyanamedsectionofcodethatcanbe"called"byname,andthecodeinsideitwillberuneachtime.Consider:
functionprintAmount(){console.log(amount.toFixed(2));}
varamount=99.99;
printAmount();//"99.99"
amount=amount*2;
printAmount();//"199.98"
Functionscanoptionallytakearguments(akaparameters)--valuesyoupassin.Andtheycanalsooptionallyreturnavalueback.
functionprintAmount(amt){console.log(amt.toFixed(2));}
functionformatAmount(){return"$"+amount.toFixed(2);}
varamount=99.99;
printAmount(amount*2);//"199.98"
amount=formatAmount();console.log(amount);//"$99.99"
ThefunctionprintAmount(..)takesaparameterthatwecallamt.ThefunctionformatAmount()returnsavalue.Ofcourse,youcanalsocombinethosetwotechniquesinthesamefunction.
Functionsareoftenusedforcodethatyouplantocallmultipletimes,buttheycanalsobeusefuljusttoorganizerelatedbitsofcodeintonamedcollections,evenifyouonlyplantocallthemonce.
Consider:
IntoProgramming
31
-
constTAX_RATE=0.08;
functioncalculateFinalPurchaseAmount(amt){//calculatethenewamountwiththetaxamt=amt+(amt*TAX_RATE);
//returnthenewamountreturnamt;}
varamount=99.99;
amount=calculateFinalPurchaseAmount(amount);
console.log(amount.toFixed(2));//"107.99"
AlthoughcalculateFinalPurchaseAmount(..)isonlycalledonce,organizingitsbehaviorintoaseparatenamedfunctionmakesthecodethatusesitslogic(theamount=calculateFinal...statement)cleaner.Ifthefunctionhadmorestatementsinit,thebenefitswouldbeevenmorepronounced.
Scope
Ifyouaskthephonestoreemployeeforaphonemodelthatherstoredoesn'tcarry,shewillnotbeabletosellyouthephoneyouwant.Sheonlyhasaccesstothephonesinherstore'sinventory.You'llhavetotryanotherstoretoseeifyoucanfindthephoneyou'relookingfor.
Programminghasatermforthisconcept:scope(technicallycalledlexicalscope).InJavaScript,eachfunctiongetsitsownscope.Scopeisbasicallyacollectionofvariablesaswellastherulesforhowthosevariablesareaccessedbyname.Onlycodeinsidethatfunctioncanaccessthatfunction'sscopedvariables.
Avariablenamehastobeuniquewithinthesamescope--therecan'tbetwodifferentavariablessittingrightnexttoeachother.Butthesamevariablenameacouldappearindifferentscopes.
IntoProgramming
32
-
functionone(){//this`a`onlybelongstothe`one()`functionvara=1;console.log(a);}
functiontwo(){//this`a`onlybelongstothe`two()`functionvara=2;console.log(a);}
one();//1two();//2
Also,ascopecanbenestedinsideanotherscope,justlikeifaclownatabirthdaypartyblowsuponeballooninsideanotherballoon.Ifonescopeisnestedinsideanother,codeinsidetheinnermostscopecanaccessvariablesfromeitherscope.
Consider:
functionouter(){vara=1;
functioninner(){varb=2;
//wecanaccessboth`a`and`b`hereconsole.log(a+b);//3}
inner();
//wecanonlyaccess`a`hereconsole.log(a);//1}
outer();
Lexicalscoperulessaythatcodeinonescopecanaccessvariablesofeitherthatscopeoranyscopeoutsideofit.
So,codeinsidetheinner()functionhasaccesstobothvariablesaandb,butcodeinouter()hasaccessonlytoa--itcannotaccessbbecausethatvariableisonlyinsideinner().
Recallthiscodesnippetfromearlier:
IntoProgramming
33
-
constTAX_RATE=0.08;
functioncalculateFinalPurchaseAmount(amt){//calculatethenewamountwiththetaxamt=amt+(amt*TAX_RATE);
//returnthenewamountreturnamt;}
TheTAX_RATEconstant(variable)isaccessiblefrominsidethecalculateFinalPurchaseAmount(..)function,eventhoughwedidn'tpassitin,becauseoflexicalscope.
Note:Formoreinformationaboutlexicalscope,seethefirstthreechaptersoftheScope&Closurestitleofthisseries.
PracticeThereisabsolutelynosubstituteforpracticeinlearningprogramming.Noamountofarticulatewritingonmypartisalonegoingtomakeyouaprogrammer.
Withthatinmind,let'strypracticingsomeoftheconceptswelearnedhereinthischapter.I'llgivethe"requirements,"andyoutryitfirst.ThenconsultthecodelistingbelowtoseehowIapproachedit.
Writeaprogramtocalculatethetotalpriceofyourphonepurchase.Youwillkeeppurchasingphones(hint:loop!)untilyourunoutofmoneyinyourbankaccount.You'llalsobuyaccessoriesforeachphoneaslongasyourpurchaseamountisbelowyourmentalspendingthreshold.Afteryou'vecalculatedyourpurchaseamount,addinthetax,thenprintoutthecalculatedpurchaseamount,properlyformatted.Finally,checktheamountagainstyourbankaccountbalancetoseeifyoucanafforditornot.Youshouldsetupsomeconstantsforthe"taxrate,""phoneprice,""accessoryprice,"and"spendingthreshold,"aswellasavariableforyour"bankaccountbalance.""Youshoulddefinefunctionsforcalculatingthetaxandforformattingthepricewitha"$"androundingtotwodecimalplaces.BonusChallenge:Trytoincorporateinputintothisprogram,perhapswiththeprompt(..)coveredin"Input"earlier.Youmayprompttheuserfortheirbankaccountbalance,forexample.Havefunandbecreative!
OK,goahead.Tryit.Don'tpeekatmycodelistinguntilyou'vegivenitashotyourself!
IntoProgramming
34
-
Note:BecausethisisaJavaScriptbook,I'mobviouslygoingtosolvethepracticeexerciseinJavaScript.Butyoucandoitinanotherlanguagefornowifyoufeelmorecomfortable.
Here'smyJavaScriptsolutionforthisexercise:
constSPENDING_THRESHOLD=200;constTAX_RATE=0.08;constPHONE_PRICE=99.99;constACCESSORY_PRICE=9.99;
varbank_balance=303.91;varamount=0;
functioncalculateTax(amount){returnamount*TAX_RATE;}
functionformatAmount(amount){return"$"+amount.toFixed(2);}
//keepbuyingphoneswhileyoustillhavemoneywhile(amount<bank_balance){//buyanewphone!amount=amount+PHONE_PRICE;
//canweaffordtheaccessory?if(amount<SPENDING_THRESHOLD){amount=amount+ACCESSORY_PRICE;}}
//don'tforgettopaythegovernment,tooamount=amount+calculateTax(amount);
console.log("Yourpurchase:"+formatAmount(amount));//Yourpurchase:$334.76
//canyouactuallyaffordthispurchase?if(amount>bank_balance){console.log("Youcan'taffordthispurchase.:(");}//Youcan'taffordthispurchase.:(
Note:ThesimplestwaytorunthisJavaScriptprogramistotypeitintothedeveloperconsoleofyournearestbrowser.
IntoProgramming
35
-
Howdidyoudo?Itwouldn'thurttotryitagainnowthatyou'veseenmycode.Andplayaroundwithchangingsomeoftheconstantstoseehowtheprogramrunswithdifferentvalues.
ReviewLearningprogrammingdoesn'thavetobeacomplexandoverwhelmingprocess.Therearejustafewbasicconceptsyouneedtowrapyourheadaround.
Theseactlikebuildingblocks.Tobuildatalltower,youstartfirstbyputtingblockontopofblockontopofblock.Thesamegoeswithprogramming.Herearesomeoftheessentialprogrammingbuildingblocks:
Youneedoperatorstoperformactionsonvalues.Youneedvaluesandtypestoperformdifferentkindsofactionslikemathonnumbersoroutputwithstrings.Youneedvariablestostoredata(akastate)duringyourprogram'sexecution.Youneedconditionalslikeifstatementstomakedecisions.Youneedloopstorepeattasksuntilaconditionstopsbeingtrue.Youneedfunctionstoorganizeyourcodeintologicalandreusablechunks.
Codecommentsareoneeffectivewaytowritemorereadablecode,whichmakesyourprogrameasiertounderstand,maintain,andfixlaterifthereareproblems.
Finally,don'tneglectthepowerofpractice.Thebestwaytolearnhowtowritecodeistowritecode.
I'mexcitedyou'rewellonyourwaytolearninghowtocode,now!Keepitup.Don'tforgettocheckoutotherbeginnerprogrammingresources(books,blogs,onlinetraining,etc.).Thischapterandthisbookareagreatstart,butthey'rejustabriefintroduction.
Thenextchapterwillreviewmanyoftheconceptsfromthischapter,butfromamoreJavaScript-specificperspective,whichwillhighlightmostofthemajortopicsthatareaddressedindeeperdetailthroughouttherestoftheseries.
IntoProgramming
36
-
Inthepreviouschapter,Iintroducedthebasicbuildingblocksofprogramming,suchasvariables,loops,conditionals,andfunctions.Ofcourse,allthecodeshownhasbeeninJavaScript.Butinthischapter,wewanttofocusspecificallyonthingsyouneedtoknowaboutJavaScripttogetupandgoingasaJSdeveloper.
WewillintroducequiteafewconceptsinthischapterthatwillnotbefullyexploreduntilsubsequentYDKJSbooks.Youcanthinkofthischapterasanoverviewofthetopicscoveredindetailthroughouttherestofthisseries.
Especiallyifyou'renewtoJavaScript,youshouldexpecttospendquiteabitoftimereviewingtheconceptsandcodeexamplesheremultipletimes.Anygoodfoundationislaidbrickbybrick,sodon'texpectthatyou'llimmediatelyunderstanditallthefirstpassthrough.
YourjourneytodeeplylearnJavaScriptstartshere.
Note:AsIsaidinChapter1,youshoulddefinitelytryallthiscodeyourselfasyoureadandworkthroughthischapter.BeawarethatsomeofthecodehereassumescapabilitiesintroducedinthenewestversionofJavaScriptatthetimeofthiswriting(commonlyreferredtoas"ES6"forthe6theditionofECMAScript--theofficialnameoftheJSspecification).Ifyouhappentobeusinganolder,pre-ES6browser,thecodemaynotwork.Arecentupdateofamodernbrowser(likeChrome,Firefox,orIE)shouldbeused.
Values&TypesAsweassertedinChapter1,JavaScripthastypedvalues,nottypedvariables.Thefollowingbuilt-intypesareavailable:
string
number
boolean
nullandundefinedobject
symbol(newtoES6)
JavaScriptprovidesatypeofoperatorthatcanexamineavalueandtellyouwhattypeitis:
IntoJavaScript
37
-
vara;typeofa;//"undefined"
a="helloworld";typeofa;//"string"
a=42;typeofa;//"number"
a=true;typeofa;//"boolean"
a=null;typeofa;//"object"--weird,bug
a=undefined;typeofa;//"undefined"
a={b:"c"};typeofa;//"object"
Thereturnvaluefromthetypeofoperatorisalwaysoneofsix(sevenasofES6!-the"symbol"type)stringvalues.Thatis,typeof"abc"returns"string",notstring.
Noticehowinthissnippettheavariableholdseverydifferenttypeofvalue,andthatdespiteappearances,typeofaisnotaskingforthe"typeofa",butratherforthe"typeofthevaluecurrentlyina."OnlyvalueshavetypesinJavaScript;variablesarejustsimplecontainersforthosevalues.
typeofnullisaninterestingcase,becauseiterrantlyreturns"object",whenyou'dexpectittoreturn"null".
Warning:Thisisalong-standingbuginJS,butonethatislikelynevergoingtobefixed.ToomuchcodeontheWebreliesonthebugandthusfixingitwouldcausealotmorebugs!
Also,notea=undefined.We'reexplicitlysettingatotheundefinedvalue,butthatisbehaviorallynodifferentfromavariablethathasnovaluesetyet,likewiththevara;lineatthetopofthesnippet.Avariablecangettothis"undefined"valuestateinseveraldifferentways,includingfunctionsthatreturnnovaluesandusageofthevoidoperator.
Objects
Theobjecttypereferstoacompoundvaluewhereyoucansetproperties(namedlocations)thateachholdtheirownvaluesofanytype.ThisisperhapsoneofthemostusefulvaluetypesinallofJavaScript.
IntoJavaScript
38
-
varobj={a:"helloworld",b:42,c:true};
obj.a;//"helloworld"obj.b;//42obj.c;//true
obj["a"];//"helloworld"obj["b"];//42obj["c"];//true
Itmaybehelpfultothinkofthisobjvaluevisually:
Propertiescaneitherbeaccessedwithdotnotation(i.e.,obj.a)orbracketnotation(i.e.,obj["a"]).Dotnotationisshorterandgenerallyeasiertoread,andisthuspreferredwhenpossible.
Bracketnotationisusefulifyouhaveapropertynamethathasspecialcharactersinit,likeobj["helloworld!"]--suchpropertiesareoftenreferredtoaskeyswhenaccessedviabracketnotation.The[]notationrequireseitheravariable(explainednext)orastringliteral(whichneedstobewrappedin".."or'..').
Ofcourse,bracketnotationisalsousefulifyouwanttoaccessaproperty/keybutthenameisstoredinanothervariable,suchas:
varobj={a:"helloworld",b:42};
varb="a";
obj[b];//"helloworld"obj["b"];//42
Note:FormoreinformationonJavaScriptobjects,seethethis&ObjectPrototypestitleofthisseries,specificallyChapter3.
ThereareacoupleofothervaluetypesthatyouwillcommonlyinteractwithinJavaScriptprograms:arrayandfunction.Butratherthanbeingproperbuilt-intypes,theseshouldbethoughtofmorelikesubtypes--specializedversionsoftheobjecttype.
IntoJavaScript
39
-
Arrays
Anarrayisanobjectthatholdsvalues(ofanytype)notparticularlyinnamedproperties/keys,butratherinnumericallyindexedpositions.Forexample:
vararr=["helloworld",42,true];
arr[0];//"helloworld"arr[1];//42arr[2];//truearr.length;//3
typeofarr;//"object"
Note:Languagesthatstartcountingatzero,likeJSdoes,use0astheindexofthefirstelementinthearray.
Itmaybehelpfultothinkofarrvisually:
Becausearraysarespecialobjects(astypeofimplies),theycanalsohaveproperties,includingtheautomaticallyupdatedlengthproperty.
Youtheoreticallycoulduseanarrayasanormalobjectwithyourownnamedproperties,oryoucoulduseanobjectbutonlygiveitnumericproperties(0,1,etc.)similartoanarray.However,thiswouldgenerallybeconsideredimproperusageoftherespectivetypes.
Thebestandmostnaturalapproachistousearraysfornumericallypositionedvaluesanduseobjectsfornamedproperties.
Functions
Theotherobjectsubtypeyou'llusealloveryourJSprogramsisafunction:
IntoJavaScript
40
-
functionfoo(){return42;}
foo.bar="helloworld";
typeoffoo;//"function"typeoffoo();//"number"typeoffoo.bar;//"string"
Again,functionsareasubtypeofobjects--typeofreturns"function",whichimpliesthatafunctionisamaintype--andcanthushaveproperties,butyoutypicallywillonlyusefunctionobjectproperties(likefoo.bar)inlimitedcases.
Note:FormoreinformationonJSvaluesandtheirtypes,seethefirsttwochaptersoftheTypes&Grammartitleofthisseries.
Built-InTypeMethods
Thebuilt-intypesandsubtypeswe'vejustdiscussedhavebehaviorsexposedaspropertiesandmethodsthatarequitepowerfulanduseful.
Forexample:
vara="helloworld";varb=3.14159;
a.length;//11a.toUpperCase();//"HELLOWORLD"b.toFixed(4);//"3.1416"
The"how"behindbeingabletocalla.toUpperCase()ismorecomplicatedthanjustthatmethodexistingonthevalue.
Briefly,thereisaString(capitalS)objectwrapperform,typicallycalleda"native,"thatpairswiththeprimitivestringtype;it'sthisobjectwrapperthatdefinesthetoUpperCase()methodonitsprototype.
Whenyouuseaprimitivevaluelike"helloworld"asanobjectbyreferencingapropertyormethod(e.g.,a.toUpperCase()intheprevioussnippet),JSautomatically"boxes"thevaluetoitsobjectwrappercounterpart(hiddenunderthecovers).
AstringvaluecanbewrappedbyaStringobject,anumbercanbewrappedbyaNumberobject,andabooleancanbewrappedbyaBooleanobject.Forthemostpart,youdon'tneedtoworryaboutordirectlyusetheseobjectwrapperformsofthevalues--
IntoJavaScript
41
-
prefertheprimitivevalueformsinpracticallyallcasesandJavaScriptwilltakecareoftherestforyou.
Note:FormoreinformationonJSnativesand"boxing,"seeChapter3oftheTypes&Grammartitleofthisseries.Tobetterunderstandtheprototypeofanobject,seeChapter5ofthethis&ObjectPrototypestitleofthisseries.
ComparingValues
TherearetwomaintypesofvaluecomparisonthatyouwillneedtomakeinyourJSprograms:equalityandinequality.Theresultofanycomparisonisastrictlybooleanvalue(trueorfalse),regardlessofwhatvaluetypesarecompared.
Coercion
WetalkedbrieflyaboutcoercioninChapter1,butlet'srevisitithere.
CoercioncomesintwoformsinJavaScript:explicitandimplicit.Explicitcoercionissimplythatyoucanseeobviouslyfromthecodethataconversionfromonetypetoanotherwilloccur,whereasimplicitcoercioniswhenthetypeconversioncanhappenasmoreofanon-obvioussideeffectofsomeotheroperation.
You'veprobablyheardsentimentslike"coercionisevil"drawnfromthefactthatthereareclearlyplaceswherecoercioncanproducesomesurprisingresults.Perhapsnothingevokesfrustrationfromdevelopersmorethanwhenthelanguagesurprisesthem.
Coercionisnotevil,nordoesithavetobesurprising.Infact,themajorityofcasesyoucanconstructwithtypecoercionarequitesensibleandunderstandable,andcanevenbeusedtoimprovethereadabilityofyourcode.Butwewon'tgomuchfurtherintothatdebate--Chapter4oftheTypes&Grammartitleofthisseriescoversallsides.
Here'sanexampleofexplicitcoercion:
vara="42";
varb=Number(a);
a;//"42"b;//42--thenumber!
Andhere'sanexampleofimplicitcoercion:
IntoJavaScript
42
-
vara="42";
varb=a*1;//"42"implicitlycoercedto42here
a;//"42"b;//42--thenumber!
Truthy&Falsy
InChapter1,webrieflymentionedthe"truthy"and"falsy"natureofvalues:whenanon-booleanvalueiscoercedtoaboolean,doesitbecometrueorfalse,respectively?
Thespecificlistof"falsy"valuesinJavaScriptisasfollows:
""(emptystring)0,-0,NaN(invalidnumber)null,undefinedfalse
Anyvaluethat'snotonthis"falsy"listis"truthy."Herearesomeexamplesofthose:
"hello"
42
true
[],[1,"2",3](arrays){},{a:42}(objects)functionfoo(){..}(functions)
It'simportanttorememberthatanon-booleanvalueonlyfollowsthis"truthy"/"falsy"coercionifit'sactuallycoercedtoaboolean.It'snotallthatdifficulttoconfuseyourselfwithasituationthatseemslikeit'scoercingavaluetoabooleanwhenit'snot.
Equality
Therearefourequalityoperators:==,===,!=,and!==.The!formsareofcoursethesymmetric"notequal"versionsoftheircounterparts;non-equalityshouldnotbeconfusedwithinequality.
Thedifferencebetween==and===isusuallycharacterizedthat==checksforvalueequalityand===checksforbothvalueandtypeequality.However,thisisinaccurate.Theproperwaytocharacterizethemisthat==checksforvalueequalitywithcoercionallowed,and===checksforvalueequalitywithoutallowingcoercion;===isoftencalled"strictequality"forthisreason.
IntoJavaScript
43
-
Considertheimplicitcoercionthat'sallowedbythe==loose-equalitycomparisonandnotallowedwiththe===strict-equality:
vara="42";varb=42;
a==b;//truea===b;//false
Inthea==bcomparison,JSnoticesthatthetypesdonotmatch,soitgoesthroughanorderedseriesofstepstocoerceoneorbothvaluestoadifferenttypeuntilthetypesmatch,wherethenasimplevalueequalitycanbechecked.
Ifyouthinkaboutit,there'stwopossiblewaysa==bcouldgivetrueviacoercion.Eitherthecomparisoncouldendupas42==42oritcouldbe"42"=="42".Sowhichisit?
Theanswer:"42"becomes42,tomakethecomparison42==42.Insuchasimpleexample,itdoesn'treallyseemtomatterwhichwaythatprocessgoes,astheendresultisthesame.Therearemorecomplexcaseswhereitmattersnotjustwhattheendresultofthecomparisonis,buthowyougetthere.
Thea===bproducesfalse,becausethecoercionisnotallowed,sothesimplevaluecomparisonobviouslyfails.Manydevelopersfeelthat===ismorepredictable,sotheyadvocatealwaysusingthatformandstayingawayfrom==.Ithinkthisviewisveryshortsighted.Ibelieve==isapowerfultoolthathelpsyourprogram,ifyoutakethetimetolearnhowitworks.
We'renotgoingtocoverallthenitty-grittydetailsofhowthecoercionin==comparisonsworkshere.Muchofitisprettysensible,buttherearesomeimportantcornercasestobecarefulof.Youcanreadsection11.9.3oftheES5specification(http://www.ecma-international.org/ecma-262/5.1/)toseetheexactrules,andyou'llbesurprisedatjusthowstraightforwardthismechanismis,comparedtoallthenegativehypesurroundingit.
Toboildownawholelotofdetailstoafewsimpletakeaways,andhelpyouknowwhethertouse==or===invarioussituations,herearemysimplerules:
Ifeithervalue(akaside)inacomparisoncouldbethetrueorfalsevalue,avoid==anduse===.Ifeithervalueinacomparisoncouldbeofthesespecificvalues(0,"",or[]--emptyarray),avoid==anduse===.Inallothercases,you'resafetouse==.Notonlyisitsafe,butinmanycasesitsimplifiesyourcodeinawaythatimprovesreadability.
IntoJavaScript
44
http://www.ecma-international.org/ecma-262/5.1/
-
Whattheserulesboildowntoisrequiringyoutothinkcriticallyaboutyourcodeandaboutwhatkindsofvaluescancomethroughvariablesthatgetcomparedforequality.Ifyoucanbecertainaboutthevalues,and==issafe,useit!Ifyoucan'tbecertainaboutthevalues,use===.It'sthatsimple.
The!=non-equalityformpairswith==,andthe!==formpairswith===.Alltherulesandobservationswejustdiscussedholdsymmetricallyforthesenon-equalitycomparisons.
Youshouldtakespecialnoteofthe==and===comparisonrulesifyou'recomparingtwonon-primitivevalues,likeobjects(includingfunctionandarray).Becausethosevaluesareactuallyheldbyreference,both==and===comparisonswillsimplycheckwhetherthereferencesmatch,notanythingabouttheunderlyingvalues.
Forexample,arraysarebydefaultcoercedtostringsbysimplyjoiningallthevalueswithcommas(,)inbetween.Youmightthinkthattwoarrayswiththesamecontentswouldbe==equal,butthey'renot:
vara=[1,2,3];varb=[1,2,3];varc="1,2,3";
a==c;//trueb==c;//truea==b;//false
Note:Formoreinformationaboutthe==equalitycomparisonrules,seetheES5specification(section11.9.3)andalsoconsultChapter4oftheTypes&Grammartitleofthisseries;seeChapter2formoreinformationaboutvaluesversusreferences.
Inequality
The<,>,=operatorsareusedforinequality,referredtointhespecificationas"relationalcomparison."Typicallytheywillbeusedwithordinallycomparablevalueslikenumbers.It'seasytounderstandthat3<4.
ButJavaScriptstringvaluescanalsobecomparedforinequality,usingtypicalalphabeticrules("bar"<"foo").
Whataboutcoercion?Similarrulesas==comparison(thoughnotexactlyidentical!)applytotheinequalityoperators.Notably,thereareno"strictinequality"operatorsthatwoulddisallowcoercionthesameway==="strictequality"does.
Consider:
IntoJavaScript
45
-
vara=41;varb="42";varc="43";
a<b;//trueb<c;//true
Whathappenshere?Insection11.8.5oftheES5specification,itsaysthatifbothvaluesinthe<comparisonarestrings,asitiswithb<c,thecomparisonismadelexicographically(akaalphabeticallylikeadictionary).Butifoneorbothisnotastring,asitiswitha<b,thenbothvaluesarecoercedtobenumbers,andatypicalnumericcomparisonoccurs.
Thebiggestgotchayoumayrunintoherewithcomparisonsbetweenpotentiallydifferentvaluetypes--remember,thereareno"strictinequality"formstouse--iswhenoneofthevaluescannotbemadeintoavalidnumber,suchas:
vara=42;varb="foo";
a<b;//falsea>b;//falsea==b;//false
Wait,howcanallthreeofthosecomparisonsbefalse?Becausethebvalueisbeingcoercedtothe"invalidnumbervalue"NaNinthe<and>comparisons,andthespecificationsaysthatNaNisneithergreater-thannorless-thananyothervalue.
The==comparisonfailsforadifferentreason.a==bcouldfailifit'sinterpretedeitheras42==NaNor"42"=="foo"--asweexplainedearlier,theformeristhecase.
Note:Formoreinformationabouttheinequalitycomparisonrules,seesection11.8.5oftheES5specificationandalsoconsultChapter4oftheTypes&Grammartitleofthisseries.
VariablesInJavaScript,variablenames(includingfunctionnames)mustbevalididentifiers.ThestrictandcompleterulesforvalidcharactersinidentifiersarealittlecomplexwhenyouconsidernontraditionalcharacterssuchasUnicode.IfyouonlyconsidertypicalASCIIalphanumericcharacters,though,therulesaresimple.
Anidentifiermuststartwitha-z,A-Z,$,or_.Itcanthencontainanyofthosecharactersplusthenumerals0-9.
IntoJavaScript
46
-
Generally,thesamerulesapplytoapropertynameastoavariableidentifier.However,certainwordscannotbeusedasvariables,butareOKaspropertynames.Thesewordsarecalled"reservedwords,"andincludetheJSkeywords(for,in,if,etc.)aswellasnull,true,andfalse.
Note:Formoreinformationaboutreservedwords,seeAppendixAoftheTypes&Grammartitleofthisseries.
FunctionScopes
Youusethevarkeywordtodeclareavariablethatwillbelongtothecurrentfunctionscope,ortheglobalscopeifatthetopleveloutsideofanyfunction.
Hoisting
Whereveravarappearsinsideascope,thatdeclarationistakentobelongtotheentirescopeandaccessibleeverywherethroughout.
Metaphorically,thisbehavioriscalledhoisting,whenavardeclarationisconceptually"moved"tothetopofitsenclosingscope.Technically,thisprocessismoreaccuratelyexplainedbyhowcodeiscompiled,butwecanskipoverthosedetailsfornow.
Consider:
vara=2;
foo();//worksbecause`foo()`//declarationis"hoisted"
functionfoo(){a=3;
console.log(a);//3
vara;//declarationis"hoisted"//tothetopof`foo()`}
console.log(a);//2
Warning:It'snotcommonoragoodideatorelyonvariablehoistingtouseavariableearlierinitsscopethanitsvardeclarationappears;itcanbequiteconfusing.It'smuchmorecommonandacceptedtousehoistedfunctiondeclarations,aswedowiththefoo()callappearingbeforeitsformaldeclaration.
IntoJavaScript
47
-
NestedScopes
Whenyoudeclareavariable,itisavailableanywhereinthatscope,aswellasanylower/innerscopes.Forexample:
functionfoo(){vara=1;
functionbar(){varb=2;
functionbaz(){varc=3;
console.log(a,b,c);//123}
baz();console.log(a,b);//12}
bar();console.log(a);//1}
foo();
Noticethatcisnotavailableinsideofbar(),becauseit'sdeclaredonlyinsidetheinnerbaz()scope,andthatbisnotavailabletofoo()forthesamereason.
Ifyoutrytoaccessavariable'svalueinascopewhereit'snotavailable,you'llgetaReferenceErrorthrown.Ifyoutrytosetavariablethathasn'tbeendeclared,you'lleitherendupcreatingavariableinthetop-levelglobalscope(bad!)orgettinganerror,dependingon"strictmode"(see"StrictMode").Let'stakealook:
functionfoo(){a=1;//`a`notformallydeclared}
foo();a;//1--oops,autoglobalvariable:(
Thisisaverybadpractice.Don'tdoit!Alwaysformallydeclareyourvariables.
Inadditiontocreatingdeclarationsforvariablesatthefunctionlevel,ES6letsyoudeclarevariablestobelongtoindividualblocks(pairsof{..}),usingtheletkeyword.Besidessomenuanceddetails,thescopingruleswillbehaveroughlythesameaswejustsawwith
IntoJavaScript
48
-
functions:
functionfoo(){vara=1;
if(a>=1){letb=2;
while(b<5){letc=b*2;b++;
console.log(a+c);}}}
foo();//579
Becauseofusingletinsteadofvar,bwillbelongonlytotheifstatementandthusnottothewholefoo()function'sscope.Similarly,cbelongsonlytothewhileloop.Blockscopingisveryusefulformanagingyourvariablescopesinamorefine-grainedfashion,whichcanmakeyourcodemucheasiertomaintainovertime.
Note:Formoreinformationaboutscope,seetheScope&Closurestitleofthisseries.SeetheES6&Beyondtitleofthisseriesformoreinformationaboutletblockscoping.
ConditionalsInadditiontotheifstatementweintroducedbrieflyinChapter1,JavaScriptprovidesafewotherconditionalsmechanismsthatweshouldtakealookat.
Sometimesyoumayfindyourselfwritingaseriesofif..else..ifstatementslikethis:
IntoJavaScript
49
-
if(a==2){//dosomething}elseif(a==10){//doanotherthing}elseif(a==42){//doyetanotherthing}else{//fallbacktohere}
Thisstructureworks,butit'salittleverbosebecauseyouneedtospecifytheatestforeachcase.Here'sanotheroption,theswitchstatement:
switch(a){case2://dosomethingbreak;case10://doanotherthingbreak;case42://doyetanotherthingbreak;default://fallbacktohere}
Thebreakisimportantifyouwantonlythestatement(s)inonecasetorun.Ifyouomitbreakfromacase,andthatcasematchesorruns,executionwillcontinuewiththenextcase'sstatementsregardlessofthatcasematching.Thissocalled"fallthrough"issometimesuseful/desired:
switch(a){case2:case10://somecoolstuffbreak;case42://otherstuffbreak;default://fallback}
IntoJavaScript
50
-
Here,ifaiseither2or10,itwillexecutethe"somecoolstuff"codestatements.
AnotherformofconditionalinJavaScriptisthe"conditionaloperator,"oftencalledthe"ternaryoperator."It'slikeamoreconciseformofasingleif..elsestatement,suchas:
vara=42;
varb=(a>41)?"hello":"world";
//similarto:
//if(a>41){//b="hello";//}//else{//b="world";//}
Ifthetestexpression(a>41here)evaluatesastrue,thefirstclause("hello")results,otherwisethesecondclause("world")results,andwhatevertheresultisthengetsassignedtob.
Theconditionaloperatordoesn'thavetobeusedinanassignment,butthat'sdefinitelythemostcommonusage.
Note:Formoreinformationabouttestingconditionsandotherpatternsforswitchand?:,seetheTypes&Grammartitleofthisseries.
StrictModeES5addeda"strictmode"tothelanguage,whichtightenstherulesforcertainbehaviors.Generally,theserestrictionsareseenaskeepingthecodetoasaferandmoreappropriatesetofguidelines.Also,adheringtostrictmodemakesyourcodegenerallymoreoptimizablebytheengine.Strictmodeisabigwinforcode,andyoushoulduseitforallyourprograms.
Youcanoptintostrictmodeforanindividualfunction,oranentirefile,dependingonwhereyouputthestrictmodepragma:
IntoJavaScript
51
-
functionfoo(){"usestrict";
//thiscodeisstrictmode
functionbar(){//thiscodeisstrictmode}}
//thiscodeisnotstrictmode
Comparethatto:
"usestrict";
functionfoo(){//thiscodeisstrictmode
functionbar(){//thiscodeisstrictmode}}
//thiscodeisstrictmode
Onekeydifference(improvement!)withstrictmodeisdisallowingtheimplicitauto-globalvariabledeclarationfromomittingthevar:
functionfoo(){"usestrict";//turnonstrictmodea=1;//`var`missing,ReferenceError}
foo();
Ifyouturnonstrictmodeinyourcode,andyougeterrors,orcodestartsbehavingbuggy,yourtemptationmightbetoavoidstrictmode.Butthatinstinctwouldbeabadideatoindulge.Ifstrictmodecausesissuesinyourprogram,almostcertainlyit'sasignthatyouhavethingsinyourprogramyoushouldfix.
Notonlywillstrictmodekeepyourcodetoasaferpath,andnotonlywillitmakeyourcodemoreoptimizable,butitalsorepresentsthefuturedirectionofthelanguage.It'dbeeasieronyoutogetusedtostrictmodenowthantokeepputtingitoff--it'llonlygethardertoconvertlater!
IntoJavaScript
52
-
Note:Formoreinformationaboutstrictmode,seetheChapter5oftheTypes&Grammartitleofthisseries.
FunctionsAsValuesSofar,we'vediscussedfunctionsastheprimarymechanismofscopeinJavaScript.Yourecalltypicalfunctiondeclarationsyntaxasfollows:
functionfoo(){//..}
Thoughitmaynotseemobviousfromthatsyntax,fooisbasicallyjustavariableintheouterenclosingscopethat'sgivenareferencetothefunctionbeingdeclared.Thatis,thefunctionitselfisavalue,justlike42or[1,2,3]wouldbe.
Thismaysoundlikeastrangeconceptatfirst,sotakeamomenttoponderit.Notonlycanyoupassavalue(argument)toafunction,butafunctionitselfcanbeavaluethat'sassignedtovariables,orpassedtoorreturnedfromotherfunctions.
Assuch,afunctionvalueshouldbethoughtofasanexpression,muchlikeanyothervalueorexpression.
Consider:
varfoo=function(){//..};
varx=functionbar(){//..};
Thefirstfunctionexpressionassignedtothefoovariableiscalledanonymousbecauseithasnoname.
Thesecondfunctionexpressionisnamed(bar),evenasareferencetoitisalsoassignedtothexvariable.Namedfunctionexpressionsaregenerallymorepreferable,thoughanonymousfunctionexpressionsarestillextremelycommon.
Formoreinformation,seetheScope&Closurestitleofthisseries.
ImmediatelyInvokedFunctionExpressions(IIFEs)
IntoJavaScript
53
-
Intheprevioussnippet,neitherofthefunctionexpressionsareexecuted--wecouldifwehadincludedfoo()orx(),forinstance.
There'sanotherwaytoexecuteafunctionexpression,whichistypicallyreferredtoasanimmediatelyinvokedfunctionexpression(IIFE):
(functionIIFE(){console.log("Hello!");})();//"Hello!"
Theouter(..)thatsurroundsthe(functionIIFE(){..})functionexpressionisjustanuanceofJSgrammarneededtopreventitfrombeingtreatedasanormalfunctiondeclaration.
Thefinal()ontheendoftheexpression--the})();line--iswhatactuallyexecutesthefunctionexpressionreferencedimmediatelybeforeit.
Thatmayseemstrange,butit'snotasforeignasfirstglance.ConsiderthesimilaritiesbetweenfooandIIFEhere:
functionfoo(){..}
//`foo`functionreferenceexpression,//then`()`executesitfoo();
//`IIFE`functionexpression,//then`()`executesit(functionIIFE(){..})();
Asyoucansee,listingthe(functionIIFE(){..})beforeitsexecuting()isessentiallythesameasincludingfoobeforeitsexecuting();inbothcases,thefunctionreferenceisexecutedwith()immediatelyafterit.
BecauseanIIFEisjustafunction,andfunctionscreatevariablescope,usinganIIFEinthisfashionisoftenusedtodeclarevariablesthatwon'taffectthesurroundingcodeoutsidetheIIFE:
IntoJavaScript
54
-
vara=42;
(functionIIFE(){vara=10;console.log(a);//10})();
console.log(a);//42
IIFEscanalsohavereturnvalues:
varx=(functionIIFE(){return42;})();
x;//42
The42valuegetsreturnedfromtheIIFE-namedfunctionbeingexecuted,andisthenassignedtox.
Closure
Closureisoneofthemostimportant,andoftenleastunderstood,conceptsinJavaScript.Iwon'tcoveritindeepdetailhere,andinsteadreferyoutotheScope&Closurestitleofthisseries.ButIwanttosayafewthingsaboutitsoyouunderstandthegeneralconcept.ItwillbeoneofthemostimportanttechniquesinyourJSskillset.
Youcanthinkofclosureasawayto"remember"andcontinuetoaccessafunction'sscope(itsvariables)evenoncethefunctionhasfinishedrunning.
Consider:
functionmakeAdder(x){//parameter`x`isaninnervariable
//innerfunction`add()`uses`x`,so//ithasa"closure"overitfunctionadd(y){returny+x;};
returnadd;}
IntoJavaScript
55
-
Thereferencetotheinneradd(..)functionthatgetsreturnedwitheachcalltotheoutermakeAdder(..)isabletorememberwhateverxvaluewaspassedintomakeAdder(..).Now,let'susemakeAdder(..):
//`plusOne`getsareferencetotheinner`add(..)`//functionwithclosureoverthe`x`parameterof//theouter`makeAdder(..)`varplusOne=makeAdder(1);
//`plusTen`getsareferencetotheinner`add(..)`//functionwithclosureoverthe`x`parameterof//theouter`makeAdder(..)`varplusTen=makeAdder(10);
plusOne(3);//4
-
functionUser(){varusername,password;
functiondoLogin(user,pw){username=user;password=pw;
//dotherestoftheloginwork}
varpublicAPI={login:doLogin};
returnpublicAPI;}
//createa`User`moduleinstancevarfred=User();
fred.login("fred","12Battery34!");
TheUser()functionservesasanouterscopethatholdsthevariablesusernameandpassword,aswellastheinnerdoLogin()function;theseareallprivateinnerdetailsofthisUsermodulethatcannotbeaccessedfromtheoutsideworld.
Warning:WearenotcallingnewUser()here,onpurpose,despitethefactthatprobablyseemsmorecommontomostreaders.User()isjustafunction,notaclasstobeinstantiated,soit'sjustcallednormally.Usingnewwouldbeinappropriateandactuallywasteresources.
ExecutingUser()createsaninstanceoftheUsermodule--awholenewscopeiscreated,andthusawholenewcopyofeachoftheseinnervariables/functions.Weassignthisinstancetofred.IfwerunUser()again,we'dgetanewinstanceentirelyseparatefromfred.
TheinnerdoLogin()functionhasaclosureoverusernameandpassword,meaningitwillretainitsaccesstothemevenaftertheUser()functionfinishesrunning.
publicAPIisanobjectwithoneproperty/methodonit,login,whichisareferencetotheinnerdoLogin()function.WhenwereturnpublicAPIfromUser(),itbecomestheinstancewecallfred.
Atthispoint,theouterUser()functionhasfinishedexecuting.Normally,you'dthinktheinnervariableslikeusernameandpasswordhavegoneaway.Butheretheyhavenot,becausethere'saclosureinthelogin()functionkeepingthemalive.
IntoJavaScript
57
-
That'swhywecancallfred.login(..)--thesameascallingtheinnerdoLogin(..)--anditcanstillaccessusernameandpasswordinnervariables.
There'sagoodchancethatwithjustthisbriefglimpseatclosureandthemodulepattern,someofitisstillabitconfusing.That'sOK!Ittakessomeworktowrapyourbrainaroundit.
Fromhere,goreadtheScope&Closurestitleofthisseriesforamuchmorein-depthexploration.
thisIdentifierAnotherverycommonlymisunderstoodconceptinJavaScriptisthethisidentifier.Again,there'sacoupleofchaptersonitinthethis&ObjectPrototypestitleofthisseries,soherewe'lljustbrieflyintroducetheconcept.
Whileitmayoftenseemthatthisisrelatedto"object-orientedpatterns,"inJSthisisadifferentmechanism.
Ifafunctionhasathisreferenceinsideit,thatthisreferenceusuallypointstoanobject.Butwhichobjectitpointstodependsonhowthefunctionwascalled.
It'simportanttorealizethatthisdoesnotrefertothefunctionitself,asisthemostcommonmisconception.
Here'saquickillustration:
functionfoo(){console.log(this.bar);}
varbar="global";
varobj1={bar:"obj1",foo:foo};
varobj2={bar:"obj2"};
//--------
foo();//"global"obj1.foo();//"obj1"foo.call(obj2);//"obj2"newfoo();//undefined
IntoJavaScript
58
-
Therearefourrulesforhowthisgetsset,andthey'reshowninthoselastfourlinesofthatsnippet.
1. foo()endsupsettingthistotheglobalobjectinnon-strictmode--instrictmode,thiswouldbeundefinedandyou'dgetanerrorinaccessingthebarproperty--so"global"isthevaluefoundforthis.bar.
2. obj1.foo()setsthistotheobj1object.3. foo.call(obj2)setsthistotheobj2object.4. newfoo()setsthistoabrandnewemptyobject.
Bottomline:tounderstandwhatthispointsto,youhavetoexaminehowthefunctioninquestionwascalled.Itwillbeoneofthosefourwaysjustshown,andthatwillthenanswerwhatthisis.
Note:Formoreinformationaboutthis,seeChapters1and2ofthethis&ObjectPrototypestitleofthisseries.
PrototypesTheprototypemechanisminJavaScriptisquitecomplicated.Wewillonlyglanceatithere.YouwillwanttospendplentyoftimereviewingChapters4-6ofthethis&ObjectPrototypestitleofthisseriesforallthedetails.
Whenyoureferenceapropertyonanobject,ifthatpropertydoesn'texist,JavaScriptwillautomaticallyusethatobject'sinternalprototypereferencetofindanotherobjecttolookforthepropertyon.Youcouldthinkofthisalmostasafallbackifthepropertyismissing.
Theinternalprototypereferencelinkagefromoneobjecttoitsfallbackhappensatthetimetheobjectiscreated.Thesimplestwaytoillustrateitiswithabuilt-inutilitycalledObject.create(..).
Consider:
varfoo={a:42};
//create`bar`andlinkitto`foo`varbar=Object.create(foo);
bar.b="helloworld";
bar.b;//"helloworld"bar.a;//42
-
Itmayhelptovisualizethefooandbarobjectsandtheirrelationship:
Theapropertydoesn'tactuallyexistonthebarobject,butbecausebarisprototype-linkedtofoo,JavaScriptautomaticallyfallsbacktolookingforaonthefooobject,whereit'sfound.
Thislinkagemayseemlikeastrangefeatureofthelanguage.Themostcommonwaythisfeatureisused--andIwouldargue,abused--istotrytoemulate/fakea"class"mechanismwith"inheritance."
Butamorenaturalwayofapplyingprototypesisapatterncalled"behaviordelegation,"whereyouintentionallydesignyourlinkedobjectstobeabletodelegatefromonetotheotherforpartsoftheneededbehavior.
Note:Formoreinformationaboutprototypesandbehaviordelegation,seeChapters4-6ofthethis&ObjectPrototypestitleofthisseries.
Old&NewSomeoftheJSfeatureswe'vealreadycovered,andcertainlymanyofthefeaturescoveredintherestofthisseries,areneweradditionsandwillnotnecessarilybeavailableinolderbrowsers.Infact,someofthenewestfeaturesinthespecificationaren'tevenimplementedinanystablebrowsersyet.
So,whatdoyoudowiththenewstuff?Doyoujusthavetowaitaroundforyearsordecadesforalltheoldbrowserstofadeintoobscurity?
That'showmanypeoplethinkaboutthesituation,butit'sreallynotahealthyapproachtoJS.
Therearetwomaintechniquesyoucanuseto"bring"thenewerJavaScriptstufftotheolderbrowsers:polyfillingandtranspiling.
Polyfilling
Theword"polyfill"isaninventedterm(byRemySharp)(https://remysharp.com/2010/10/08/what-is-a-polyfill)usedtorefertotakingthedefinitionofanewerfeatureandproducingapieceofcodethat'sequivalenttothebehavior,butisabletoruninolderJSenvironments.
IntoJavaScript
60
https://remysharp.com/2010/10/08/what-is-a-polyfill
-
Forexample,ES6definesautilitycalledNumber.isNaN(..)toprovideanaccuratenon-buggycheckforNaNvalues,deprecatingtheoriginalisNaN(..)utility.Butit'seasytopolyfillthatutilitysothatyoucanstartusingitinyourcoderegardlessofwhethertheenduserisinanES6browserornot.
Consider:
if(!Number.isNaN){Number.isNaN=functionisNaN(x){returnx!==x;};}
TheifstatementguardsagainstapplyingthepolyfilldefinitioninES6browserswhereitwillalreadyexist.Ifit'snotalreadypresent,wedefineNumber.isNaN(..).
Note:ThecheckwedoheretakesadvantageofaquirkwithNaNvalues,whichisthatthey'retheonlyvalueinthewholelanguagethatisnotequaltoitself.SotheNaNvalueistheonlyonethatwouldmakex!==xbetrue.
Notallnewfeaturesarefullypolyfillable.Sometimesmostofthebehaviorcanbepolyfilled,buttherearestillsmalldeviations.Youshouldbereally,reallycarefulinimplementingapolyfillyourself,tomakesureyouareadheringtothespecificationasstrictlyaspossible.
Orbetteryet,useanalreadyvettedsetofpolyfillsthatyoucantrust,suchasthoseprovidedbyES5-Shim(https://github.com/es-shims/es5-shim)andES6-Shim(https://github.com/es-shims/es6-shim).
Transpiling
There'snowaytopolyfillnewsyntaxthathasbeenaddedtothelanguage.ThenewsyntaxwouldthrowanerrorintheoldJSengineasunrecognized/invalid.
Sothebetteroptionistouseatoolthatconvertsyournewercodeintooldercodeequivalents.Thisprocessiscommonlycalled"transpiling,"atermfortransforming+compiling.
Essentially,yoursourcecodeisauthoredinthenewsyntaxform,butwhatyoudeploytothebrowseristhetranspiledcodeinoldsyntaxform.Youtypicallyinsertthetranspilerintoyourbuildprocess,similartoyourcodelinteroryourminifier.
Youmightwonderwhyyou'dgotothetroubletowritenewsyntaxonlytohaveittranspiledawaytooldercode--whynotjustwritetheoldercodedirectly?
Thereareseveralimportantreasonsyoushouldcareabouttranspiling:
IntoJavaScript
61
https://github.com/es-shims/es5-shimhttps://github.com/es-shims/es6-shim
-
Thenewsyntaxaddedtothelanguageisdesignedtomakeyourcodemorereadableandmaintainable.Theolderequivalentsareoftenmuchmoreconvoluted.Youshouldpreferwritingnewerandcleanersyntax,notonlyforyourselfbutforallothermembersofthedevelopmentteam.Ifyoutranspileonlyforolderbrowsers,butservethenewsyntaxtothenewestbrowsers,yougettotakeadvantageofbrowserperformanceoptimizationswiththenewsyntax.Thisalsoletsbrowsermakershavemorereal-worldcodetotesttheirimplementationsandoptimizationson.Usingthenewsyntaxearlierallowsittobetestedmorerobustlyintherealworld,whichprovidesearlierfeedbacktotheJavaScriptcommittee(TC39).Ifissuesarefoundearlyenough,theycanbechanged/fixedbeforethoselanguagedesignmistakesbecomepermanent.
Here'saquickexampleoftranspiling.ES6addsafeaturecalled"defaultparametervalues."Itlookslikethis:
functionfoo(a=2){console.log(a);}
foo();//2foo(42);//42
Simple,right?Helpful,too!Butit'snewsyntaxthat'sinvalidinpre-ES6engines.Sowhatwillatranspilerdowiththatcodetomakeitruninolderenvironments?
functionfoo(){vara=arguments[0]!==(void0)?arguments[0]:2;console.log(a);}
Asyoucansee,itcheckstoseeifthearguments[0]valueisvoid0(akaundefined),andifsoprovidesthe2defaultvalue;otherwise,itassignswhateverwaspassed.
Inadditiontobeingabletonowusethenicersyntaxeveninolderbrowsers,lookingatthetranspiledcodeactuallyexplainstheintendedbehaviormoreclearly.
YoumaynothaverealizedjustfromlookingattheES6versionthatundefinedistheonlyvaluethatcan'tgetexplicitlypassedinforadefault-valueparameter,butthetranspiledcodemakesthatmuchmoreclear.
ThelastimportantdetailtoemphasizeabouttranspilersisthattheyshouldnowbethoughtofasastandardpartoftheJSdevelopmentecosystemandprocess.JSisgoingtocontinuetoevolve,muchmorequicklythanbefore,soeveryfewmonthsnewsyntaxandnew
IntoJavaScript
62
-
featureswillbeadded.
Ifyouuseatranspilerbydefault,you'llalwaysbeabletomakethatswitchtonewersyntaxwheneveryoufindituseful,ratherthanalwayswaitingforyearsfortoday'sbrowserstophaseout.
Therearequiteafewgreattranspilersforyoutochoosefrom.Herearesomegoodoptionsatthetimeofthiswriting:
Babel(https://babeljs.io)(formerly6to5):TranspilesES6+intoES5Traceur(https://github.com/google/traceur-compiler):TranspilesES6,ES7,andbeyondintoES5
Non-JavaScriptSofar,theonlythingswe'vecoveredareintheJSlanguageitself.TherealityisthatmostJSiswrittentoruninandinteractwithenvironmentslikebrowsers.Agoodchunkofthestuffthatyouwriteinyourcodeis,strictlyspeaking,notdirectlycontrolledbyJavaScript.Thatprobablysoundsalittlestrange.
Themostcommonnon-JavaScriptJavaScriptyou'llencounteristheDOMAPI.Forexample:
varel=document.getElementById("foo");
Thedocumentvariableexistsasaglobalvariablewhenyourcodeisrunninginabrowser.It'snotprovidedbytheJSengine,norisitparticularlycontrolledbytheJavaScriptspecification.IttakestheformofsomethingthatlooksanawfullotlikeanormalJSobject,butit'snotreallyexactlythat.It'saspecialobject,oftencalleda"hostobject."
Moreover,thegetElementById(..)methodondocumentlookslikeanormalJSfunction,butit'sjustathinlyexposedinterfacetoabuilt-inmethodprovidedbytheDOMfromyourbrowser.Insome(newer-generation)browsers,thislayermayalsobeinJS,buttraditionallytheDOManditsbehaviorisimplementedinsomethingmorelikeC/C++.
Anotherexampleiswithinput/output(I/O).
Everyone'sfavoritealert(..)popsupamessageboxintheuser'sbrowserwindow.alert(..)isprovidedtoyourJSprogrambythebrowser,notbytheJSengineitself.Thecallyoumakesendsthemessagetothebrowserinternalsandithandlesdrawinganddisplayingthemessagebox.
IntoJavaScript
63
https://babeljs.iohttps://github.com/google/traceur-compiler
-
Thesamegoeswithconsole.log(..);yourbrowserprovidessuchmechanismsandhooksthemuptothedevelopertools.
Thisbook,andthiswholeseries,focusesonJavaScriptthelanguage.That'swhyyoudon'tseeanysubstantialcoverageofthesenon-JavaScriptJavaScriptmechanisms.Nevertheless,youneedtobeawareofthem,asthey'llbeineveryJSprogramyouwrite!
ReviewThefirststeptolearningJavaScript'sflavorofprogrammingistogetabasicunderstandingofitscoremechanismslikevalues,types,functionclosures,this,andprototypes.
Ofcourse,eachofthesetopicsdeservesmuchgreatercoveragethanyou'veseenhere,butthat'swhytheyhavechaptersandbooksdedicatedtothemthroughouttherestofthisseries.Afteryoufeelprettycomfortablewiththeconceptsandcodesamplesinthischapter,therestoftheseriesawaitsyoutoreallydiginandgettoknowthelanguagedeeply.
Thefinalchapterofthisbookwillbrieflysummarizeeachoftheothertitlesintheseriesandtheotherconceptstheycoverbesideswhatwe'vealreadyexplored.
IntoJavaScript
64
-
Whatisthisseriesallabout?Putsimply,it'sabouttakingseriouslythetaskoflearningallpartsofJavaScript,notjustsomesubsetofthelanguagethatsomeonecalled"thegoodparts,"andnotjustwhateverminimalamountyouneedtogetyourjobdoneatwork.
Seriousdevelopersinotherlanguagesexpecttoputintheefforttolearnmostorallofthelanguage(s)theyprimarilywritein,butJSdevelopersseemtostandoutfromthecrowdinthesenseoftypicallynotlearningverymuchofthelanguage.Thisisnotagoodthing,andit'snotsomethingweshouldcontinuetoallowtobethenorm.
TheYouDon'tKnowJS(YDKJS)seriesstandsinstarkcontrasttothetypicalapproachestolearningJS,andisunlikealmostanyotherJSbooksyouwillread.Itchallengesyoutogobeyondyourcomfortzoneandtoaskthedeeper"why"questionsforeverysinglebehavioryouencounter.Areyouupforthatchallenge?
I'mgoingtousethisfinalchaptertobrieflysummarizewhattoexpectfromtherestofthebooksintheseries,andhowtomosteffectivelygoaboutbuildingafoundationofJSlearningontopofYDKJS.
Scope&ClosuresPerhapsoneofthemostfundamentalthingsyou'llneedtoquicklycometotermswithishowscopingofvariablesreallyworksinJavaScript.It'snotenoughtohaveanecdotalfuzzybeliefsaboutscope.
TheScope&ClosurestitlestartsbydebunkingthecommonmisconceptionthatJSisan"interpretedlanguage"andthereforenotcompiled.Nope.
TheJSenginecompilesyourcoderightbefore(andsometimesduring!)execution.Soweusesomedeeperunderstandingofthecompiler'sapproachtoourcodetounderstandhowitfindsanddealswithvariableandfunctiondeclarations.Alongtheway,weseethetypicalmetaphorforJSvariablescopemanagement,"Hoisting."
Thiscriticalunderstandingof"lexicalscope"iswhatwethenbaseourexplorationofclosureonforthelastchapterofthebook.ClosureisperhapsthesinglemostimportantconceptinallofJS,butifyouhaven'tfirstgraspedfirmlyhowscopeworks,closurewilllikelyremainbeyondyourgrasp.
Oneimportantapplicationofclosureisthemodulepattern,aswebrieflyintroducedinthisbookinChapter2.ThemodulepatternisperhapsthemostprevalentcodeorganizationpatterninallofJavaScript;deepunderstandingofitshouldbeoneofyourhighestpriorities.
this&ObjectPrototypes
IntoYDKJS
65
-
PerhapsoneofthemostwidespreadandpersistentmistruthsaboutJavaScriptisthatthethiskeywordreferstothefunctionitappearsin.Terriblymistaken.
Thethiskeywordisdynamicallyboundbasedonhowthefunctioninquestionisexecuted,anditturnsouttherearefoursimplerulestounderstandandfullydeterminethisbinding.
Closelyrelatedtothethiskeywordistheobjectprototypemechanism,whichisalook-upchainforproperties,similartohowlexicalscopevariablesarefound.ButwrappedupintheprototypesistheotherhugemiscueaboutJS:theideaofemulating(fake)classesand(so-called"prototypal")inheritance.
Unfortunately,thedesiretobringclassandinheritancedesignpatternthinkingtoJavaScriptisjustabouttheworstthingyoucouldtrytodo,becausewhilethesyntaxmaytrickyouintothinkingthere'ssomethinglikeclassespresent,infacttheprototypemechanismisfundamentallyoppositeinitsbehavior.
What'satissueiswhetherit'sbettertoignorethemismatchandpretendthatwhatyou'reimplementingis"inheritance,"orwhetherit'smoreappropriatetolearnandembracehowtheobjectprototypesystemactuallyworks.Thelatterismoreappropriatelynamed"behaviordelegation."
Thisismorethansyntacticpreference.Delegationisanentirelydifferent,andmorepowerful,designpattern,onethatreplacestheneedtodesignwithclassesandinheritance.Buttheseassertionswillabsolutelyflyinthefaceofnearlyeveryotherblogpost,book,andconferencetalkonthesubjectfortheentiretyofJavaScript'slifetime.
TheclaimsImakeregardingdelegationversusinheritancecomenotfromadislikeofthelanguageanditssyntax,butfromthedesiretoseethetruecapabilityofthelanguageproperlyleveragedandtheendlessconfusionandfrustrationwipedaway.
ButthecaseImakeregardingprototypesanddelegationisamuchmoreinvolvedonethanwhatIwillindulgehere.Ifyou'rereadytoreconsidereverythingyouthinkyouknowaboutJavaScript"classes"and"inheritance,"Iofferyouthechanceto"taketheredpill"(Matrix1999)andcheckoutChapters4-6ofthethis&ObjectPrototypestitleofthisseries.
Types&GrammarThethirdtitleinthisseriesprimarilyfocusesontacklingyetanotherhighlycontroversialtopic:typecoercion.PerhapsnotopiccausesmorefrustrationwithJSdevelopersthanwhenyoutalkabouttheconfusionssurroundingimplicitcoercion.
IntoYDKJS
66
-
Byfar,theconventionalwisdomisthatimplicitcoercionisa"badpart"ofthelanguageandshouldbeavoidedatallcosts.Infact,somehavegonesofarastocallita"flaw"inthedesignofthelanguage.Indeed,therearetoolswhoseentirejobistodonothingbutscanyourcodeandcomplainifyou'redoinganythingevenremotelylikecoercion.
Butiscoercionreallysoconfusing,sobad,sotreacherous,thatyourcodeisdoomedfromthestartifyouuseit?
Isayno.AfterhavingbuiltupanunderstandingofhowtypesandvaluesreallyworkinChapters1-3,Chapter4takesonthisdebateandfullyexplainshowcoercionworks,inallitsnooksandcrevices.Weseejustwhatpartsofcoercionreallyaresurprisingandwhatpartsactuallymakecompletesenseifgiventhetimetolearn.
ButI'mnotmerelysuggestingthatcoercionissensibleandlearnable,I'massertingthatcoercionisanincrediblyusefulandtotallyunderestimatedtoolthatyoushouldbeusinginyourcode.I'msayingthatcoercion,whenusedproperly,notonlyworks,butmakesyourcodebetter.Allthenaysayersanddoubterswillsurelyscoffatsuchaposition,butIbelieveit'soneofthemainkeystouppingyourJSgame.
Doyouwanttojustkeepfollowingwhatthecrowdsays,orareyouwillingtosetalltheassumptionsasideandlookatcoercionwithafreshperspective?TheTypes&Grammartitleofthisserieswillcoerceyourthinking.
Async&PerformanceThefirstthreetitlesofthisseriesfocusonthecoremechanicsofthelanguage,butthefourthtitlebranchesoutslightlytocoverpatternsontopofthelanguagemechanicsformanagingasynchronousprogramming.Asynchronyisnotonlycriticaltotheperformanceofourapplications,it'sincreasinglybecomingthecriticalfactorinwritabilityandmaintainability.
Thebookstartsfirstbyclearingupalotofterminologyandconceptconfusionaroundthingslike"async,""parallel,"and"concurrent,"andexplainsindepthhowsuchthingsdoanddonotapplytoJS.
Thenwemoveintoexaminingcallbacksastheprimarymethodofenablingasynchrony.Butit'sherethatwequicklyseethatthecallbackaloneishopelesslyinsufficientforthemoderndemandsofasynchronousprogramming.Weidentifytwomajordeficienciesofcallbacks-onlycoding:InversionofControl(IoC)trustlossandlackoflinearreason-ability.
Toaddressthesetwomajordeficiencies,ES6introducestwonewmechanisms(andindeed,patterns):promisesandgenerators.
IntoYDKJS
67
-
Promisesareatime-independentwrapperarounda"futurevalue,"whichletsyoureasonaboutandcomposethemregardlessofifthevalueisreadyornotyet.Moreover,theyeffectivelysolvetheIoCtrustissuesbyroutingcallbacksthroughatrustableandcomposablepromisemechanism.
GeneratorsintroduceanewmodeofexecutionforJSfunctions,wherebythegeneratorcanbepausedatyieldpointsandberesumedasynchronouslylater.Thepause-and-resumecapabilityenablessynchronous,sequentiallookingcodeinthegeneratortobeprocessedasynchronouslybehindthescenes.Bydoingso,weaddressthenon-linear,non-local-jumpconfusionsofcallbacksandtherebymakeourasynchronouscodesync-lookingsoastobemorereason-able.
Butit'sthecombinationofpromisesandgeneratorsthat"yields"ourmosteffectiveasynchronouscodingpatterntodateinJavaScript.Infact,muchofthefuturesophisticationofasynchronycominginES7andlaterwillcertainlybebuiltonthisfoundation.Tobeseriousaboutprogrammingeffectivelyinanasyncworld,you'regoingtoneedtogetreallycomfortablewithcombiningpromisesandgenerators.
Ifpromisesandgeneratorsareaboutexpressingpatternsthatletourprogramsrunmoreconcurrentlyandthusgetmoreprocessingaccomplishedinashorterperiod,JShasmanyotherfacetsofperformanceoptimizationworthexploring.
Chapter5delvesintotopicslikeprogramparallelismwithWebWorkersanddataparallelismwithSIMD,aswellaslow-leveloptimizationtechniqueslikeASM.js.Chapter6takesalookatperformanceoptimizationfromtheperspectiveofproperbenchmarkingtechniques,includingwhatkindsofperformancetoworryaboutandwhattoignore.
WritingJavaScripteffectivelymeanswritingcodethatcanbreaktheconstraintbarriersofbeingrundynamicallyinawiderangeofbrowsersandotherenvironments.Itrequiresalotofintricateanddetailedplanningandeffortonourpartstotakeaprogramfrom"itworks"to"itworkswell."
TheAsync&PerformancetitleisdesignedtogiveyouallthetoolsandskillsyouneedtowritereasonableandperformantJavaScriptcode.
ES6&BeyondNomatterhowmuchyoufeelyou'vemasteredJavaScripttothispoint,thetruthisthatJavaScriptisnevergoingtosto