155
1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 Table of Contents Eloquent JavaScript Introducción 1. Valores, Tipos y Operadores 2. Estructura del Programa 3. Funciones 4. Estructuras de Datos: Objetos y Arreglos 5. Funciones de Order Superior 6. La Vida Secreta De Los Objetos 7. Proyecto: Vida Electronica 1

Table of Contents - Holacodigo | tutoriales de

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

11

12

13

14

15

16

17

18

19

TableofContentsEloquentJavaScript

Introduccioacuten

1ValoresTiposyOperadores

2EstructuradelPrograma

3Funciones

4EstructurasdeDatosObjetosyArreglos

5FuncionesdeOrderSuperior

6LaVidaSecretaDeLosObjetos

7ProyectoVidaElectronica

1

EloquentJavascriptenEspantildeol

EloquentJavaScript

2

IntroduccioacutenEstelibrotratadecomohacerquelascomputadorashaganloquetuacutequieresquehaganLascomputadorassontancomunescomolosdesatornilladoreshoyendiacuteaperotienenmuchamaacutescomplejidadocultayporlotantosonmaacutesdifiacutecilesdeoperaryentenderParamuchossiguensiendocosasextrantildeasunpocoamenazadoras

HemosencontradodosformasefectivasdecerrarlabrechaentenosotrossuavesorganismosbioloacutegicoscontalentoparaelrazonamientosocialyespacialylascomputadorasmanipuladorassinsentimientosdedatossinsentidoLaprimeraesusarnuestrossentidosdelmundofiacutesicoyconstruirinterfacesqueimitanesemundoynospermitenmanipularfigurasenunapantallaconnuestrosdedosEstofuncionamuybienparainteraccionescasualesconlamaacutequina

PeroauacutennohemosencontradounabuenaformadeusarlainterfazgraacuteficaparacomunicaralacomputadoracosasqueeldisentildeadordeinterfacesnoanticipoacuteParainterfacesabiertascomoindicarlealacomputadoraqueejecutetareasarbitrariashemostenidomaacutessuerteconotraestrategiaquehaceusodenuestrotalentoparaellenguajeensentildearlealacomputadorauno

LoslenguajeshumanospermitenquepalabrasyfrasessecombinenenmuchasdiferentesformaslocuaacutelnospermitedecirunaampliavariedaddecosasLoslenguajescomputacionalesaunquesongramaticalmentemenosflexiblessiguenunprincipiosimilar

Lacomputacioacutencasualsehaextendidomuchoenlosuacuteltimos20antildeosylasinterfacesbasadasenellenguajequealgunavezfueronlaformapredeterminadaenlaquelaspersonasinteractuabanconlascomputadorashansidoreemplazadasengranmedidaporinterfacesgraacuteficasPerotodaviacuteaestaacutenahiacutesisabesdondebuscarUnodeestoslenguajesJavaScriptestaacutepresenteencasitodoslosnavegadoreswebexistentesyporlotantodisponibleenpraacutecticamentetodoslosdispositivosdeconsumo

Introduccioacuten

3

Estelibrotratadehacerquetefamiliariceslosuficienteconestelenguajeparaquepuedashacerquelacomputadorahagaloquetuacutequieras

EnlaProgramacioacuten

NoiluminoaaquellosquenoestaacutendeseososdeaprendertampocodespiertoaquienesnoestaacutenansiososdedarseunaexplicacioacutenasiacutemismosSileshepresentadounaesquinadelcuadroyellosnovienenconlasotrastresnodeberiacutearecorrerotravezlospuntosConfucio

ApartedeexplicarJavaScriptteintroducireacuteenlosprincipiosbaacutesicosdelaprogramacioacutenProgramarresultadifiacutecilLasreglasfundamentalestiacutepicamentesonsimplesyclarasPerolosprogramascontruidossobreesasreglastiendenavolverselosuficientementecomplejosparaintroducirsuspropiasreglasymaacutescomplejidadEnciertaformaestaacutesconstruyendotupropiolaberintoypodriacuteasperderteeneacutel

HabraacuteocasionesenlasquealleerestelibrotesentiraacutesterriblementefrustradoSieresnuevoprogramandotendraacutesmuchomaterialnuevoparadigerirMuchodeestematerialdespueacutesseraacutecombinadoenformasquerequeriraacutenquehagasconexionesadicionales

EsturesponsabilidadrealizarelesfuerzonecesarioCuandosetehagadifiacutecilseguirestelibronoconcluyasraacutepidamentenadaacercadetuscapacidadesTueresbuenomdashsoacutelonecesitasmantenerelpasoTomaunrespirovuelvealeerelmaterialysiempreaseguacuteratedeleeryentenderlosprogramasdeejemploylosejerciciosAprenderesuntrabajoduroperotodoloqueaprendasahoraestuyoyharaacuteelaprendizajecadavezmaacutesfaacutecil

ElprogramadordecomputadoraseselcreadordeuniversosdeloscualeseacutelsoacuteloesresponsableUniversosdecomplejidadvirtualmenteilimitadapuedensercreadosenlaformadeprogramasdecomputadora

JosephWeizenbaumComputerPowerandHumanReason

UnprogramaesmuchascosasEsunapiezadetextoescritaporunprogramadoreslafuerzaquedirijealacomputadoraparahacerloquehacesondatosenlamemoriadelacomputadorayauacutenasiacutecontrolalasaccionesrealizadasenestamismamemoriaLasanalogiacuteasquetratandecompararalascomputadorasconobjetosqueconocemostiendenaquedarsecortasUnaqueseajustasuperficialmenteeslademaacutequinaunmontoacutendepiezasseparadasqueserelacionanyparahacerlofuncionartenemosqueconsiderarlasformasenqueesaspiezasseinterconectanycontribuyenalfuncionamientodeltodo

UnacomputadoraesunamaacutequinaqueactuacomoanfitrionadeestasmaacutequinasinmaterialesLascomputadorasporsiacutemismassoacutelopuedenhacercosasestuacutepidamentesimplesLarazoacutenporlaquesontanpoderosasesquehacenesascosasaunavelocidad

Introduccioacuten

4

increiacuteblementeraacutepidaUnprogramapuedecombinaringeniosamenteunnuacutemeroenormedeesasaccionessimplesparalograrcosasmuycomplicadas

ParaalgunosdenosotrosescribirprogramasdecomputadorasesunjuegofascinanteUnprogramaesunconstruccioacutendelpensamientoNotienecostoconstruirlonopesanadaycrecefaacutecilmentebajonuestrasmanostecleando

PerosinotenemoscuidadoeltamantildeoylacomplejidaddeunprogramasesaldraacutendecontrolconfundiendoinclusoalapersonaquelocreoacuteMantenerlosprogramasbajocontroleselprincipalproblemadelaprogramacioacutenCuandofuncionaneshermosoElartedeprogramareslahabilidaddecontrolarlacomplejidadUngranprogramaestaacutedominadohechosimpleensucomplejidad

MuchosprogramadorescreenqueestacomplejidadesmejorcontroladausandosoacutelounpequentildeoconjuntodeteacutecnicasbienentendidasensusprogramasEstoshancompuestoreglasestrictas(ldquomejorespraacutecticasrdquo)queprescribenlaformaquelosprogramasdeberiacuteantenerylosmaacutescelososdeellosconsideraraacutenaaquellosquesesalendeestapequentildeazonaseguracomomalosprogramadores

iexclQueacutehostilidadhacialariquezadelaprogramacioacutenladetratardereducirlaaalgosimpleypredecibletratardehacertabuacuteatodoslosprogramasextrantildeosybellosElpanoramadetodaslasteacutecnicasdeprogramacioacutenesenormefascinanteensudiversidadypermaneceinexploradoengranparteCiertamenteespeligrosoiraseduciendoalprogramadornovatocontodotipodeconfusionesperoesosoacutelosignificaquedebesdeandarconcuidadoyestaralertaConformevayasaprendiendosiemprehabraacutenuevosretosynuevoterritorioporexplorarLosprogramadoresquesenieguenaexplorardejaraacutendeprogresarolvidaraacutensualegriacuteayseaburriraacutenconsutrabajo

Porqueacuteellenguajeimporta

EnelprincipiocuandonacioacutelacomputacioacutennohabiacutealenguajesdeprogramacioacutenLosprogrmasluciacuteanalgoasiacute

001100010000000000000000001100010000000100000001001100110000000100000010010100010000101100000010001000100000001000001000010000110000000100000000010000010000000100000001000100000000001000000000011000100000000000000000

Introduccioacuten

5

Esoesunprogramaparasumarlosnuacutemerosdel1al10eimprimirelresultado1+2++10=55PodriacuteacorrerenunasimplehipoteacuteticamaacutequinaParaprogramarlasprimerascomputadoraseranecesarioconfigurargrandesconjuntosdeinterruptoresenlaposicioacutencorrectaoperforartirasdetarjetaseintroducirlasenlacomputadoraProbablementetepuedesimaginarcuantediosoypropensoalerroreraesteprocedimientoInclusoescribirprogramassimplesrequeriacuteagraninteligenciaydisciplinaLosprogramascomplejoserancasiinconcebibles

Clarointroducirmanualmenteestososcurospatronesdebits(losunosyceros)dieronalprogramadorunprofundosentimientodeserunpoderosomagoYesohavalidoalgoenteacuterminosdesatisfaccioacuteneneltrabajo

CadaliacuteneadelprogramaanteriorcontieneunainstruccioacutenPodriacuteaserescritaenespantildeolcomosigue

1 Guardaelnuacutemero0enladireccioacutendememoria02 Guardaelnuacutemero1enladireccioacutendememoria13 Guardaelvalordeladireccioacutendememoria1enladireccioacuten24 Resta11delvalorenladireccioacutendememoria25 Sielvalorenladireccioacutendememoria2eselnuacutemero0continuacuteaconlainstruccioacuten96 Sumaelvalordeladireccioacutendememoria1alvalordeladireccioacutendememoria07 Suma1alvalordeladireccioacutendememoria18 Continuacuteaconlainstruccioacuten39 Devuelveelvalordeladireccioacutendememoria0

AunqueesoesmaacuteslegiblequeunasopadebitssiguesinseragradablePodriacuteaayudarusarnombresenlosnuacutemerosparalasinstruccionesydireccionesdememoria

Ponldquototalrdquoiguala0Ponldquoconteordquoiguala1[bucle]PonldquocomparacioacutenrdquoigualaldquoconteordquoResta11deldquocomparacioacutenrdquoSildquocomparacioacutenrdquoescerocontinuacuteaen[final]SumaldquoconteordquoaldquototalrdquoSuma1aldquoconteordquoContinuacuteaen[bucle][final]Devuelveldquototalrdquo

Introduccioacuten

6

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

EloquentJavascriptenEspantildeol

EloquentJavaScript

2

IntroduccioacutenEstelibrotratadecomohacerquelascomputadorashaganloquetuacutequieresquehaganLascomputadorassontancomunescomolosdesatornilladoreshoyendiacuteaperotienenmuchamaacutescomplejidadocultayporlotantosonmaacutesdifiacutecilesdeoperaryentenderParamuchossiguensiendocosasextrantildeasunpocoamenazadoras

HemosencontradodosformasefectivasdecerrarlabrechaentenosotrossuavesorganismosbioloacutegicoscontalentoparaelrazonamientosocialyespacialylascomputadorasmanipuladorassinsentimientosdedatossinsentidoLaprimeraesusarnuestrossentidosdelmundofiacutesicoyconstruirinterfacesqueimitanesemundoynospermitenmanipularfigurasenunapantallaconnuestrosdedosEstofuncionamuybienparainteraccionescasualesconlamaacutequina

PeroauacutennohemosencontradounabuenaformadeusarlainterfazgraacuteficaparacomunicaralacomputadoracosasqueeldisentildeadordeinterfacesnoanticipoacuteParainterfacesabiertascomoindicarlealacomputadoraqueejecutetareasarbitrariashemostenidomaacutessuerteconotraestrategiaquehaceusodenuestrotalentoparaellenguajeensentildearlealacomputadorauno

LoslenguajeshumanospermitenquepalabrasyfrasessecombinenenmuchasdiferentesformaslocuaacutelnospermitedecirunaampliavariedaddecosasLoslenguajescomputacionalesaunquesongramaticalmentemenosflexiblessiguenunprincipiosimilar

Lacomputacioacutencasualsehaextendidomuchoenlosuacuteltimos20antildeosylasinterfacesbasadasenellenguajequealgunavezfueronlaformapredeterminadaenlaquelaspersonasinteractuabanconlascomputadorashansidoreemplazadasengranmedidaporinterfacesgraacuteficasPerotodaviacuteaestaacutenahiacutesisabesdondebuscarUnodeestoslenguajesJavaScriptestaacutepresenteencasitodoslosnavegadoreswebexistentesyporlotantodisponibleenpraacutecticamentetodoslosdispositivosdeconsumo

Introduccioacuten

3

Estelibrotratadehacerquetefamiliariceslosuficienteconestelenguajeparaquepuedashacerquelacomputadorahagaloquetuacutequieras

EnlaProgramacioacuten

NoiluminoaaquellosquenoestaacutendeseososdeaprendertampocodespiertoaquienesnoestaacutenansiososdedarseunaexplicacioacutenasiacutemismosSileshepresentadounaesquinadelcuadroyellosnovienenconlasotrastresnodeberiacutearecorrerotravezlospuntosConfucio

ApartedeexplicarJavaScriptteintroducireacuteenlosprincipiosbaacutesicosdelaprogramacioacutenProgramarresultadifiacutecilLasreglasfundamentalestiacutepicamentesonsimplesyclarasPerolosprogramascontruidossobreesasreglastiendenavolverselosuficientementecomplejosparaintroducirsuspropiasreglasymaacutescomplejidadEnciertaformaestaacutesconstruyendotupropiolaberintoypodriacuteasperderteeneacutel

HabraacuteocasionesenlasquealleerestelibrotesentiraacutesterriblementefrustradoSieresnuevoprogramandotendraacutesmuchomaterialnuevoparadigerirMuchodeestematerialdespueacutesseraacutecombinadoenformasquerequeriraacutenquehagasconexionesadicionales

EsturesponsabilidadrealizarelesfuerzonecesarioCuandosetehagadifiacutecilseguirestelibronoconcluyasraacutepidamentenadaacercadetuscapacidadesTueresbuenomdashsoacutelonecesitasmantenerelpasoTomaunrespirovuelvealeerelmaterialysiempreaseguacuteratedeleeryentenderlosprogramasdeejemploylosejerciciosAprenderesuntrabajoduroperotodoloqueaprendasahoraestuyoyharaacuteelaprendizajecadavezmaacutesfaacutecil

ElprogramadordecomputadoraseselcreadordeuniversosdeloscualeseacutelsoacuteloesresponsableUniversosdecomplejidadvirtualmenteilimitadapuedensercreadosenlaformadeprogramasdecomputadora

JosephWeizenbaumComputerPowerandHumanReason

UnprogramaesmuchascosasEsunapiezadetextoescritaporunprogramadoreslafuerzaquedirijealacomputadoraparahacerloquehacesondatosenlamemoriadelacomputadorayauacutenasiacutecontrolalasaccionesrealizadasenestamismamemoriaLasanalogiacuteasquetratandecompararalascomputadorasconobjetosqueconocemostiendenaquedarsecortasUnaqueseajustasuperficialmenteeslademaacutequinaunmontoacutendepiezasseparadasqueserelacionanyparahacerlofuncionartenemosqueconsiderarlasformasenqueesaspiezasseinterconectanycontribuyenalfuncionamientodeltodo

UnacomputadoraesunamaacutequinaqueactuacomoanfitrionadeestasmaacutequinasinmaterialesLascomputadorasporsiacutemismassoacutelopuedenhacercosasestuacutepidamentesimplesLarazoacutenporlaquesontanpoderosasesquehacenesascosasaunavelocidad

Introduccioacuten

4

increiacuteblementeraacutepidaUnprogramapuedecombinaringeniosamenteunnuacutemeroenormedeesasaccionessimplesparalograrcosasmuycomplicadas

ParaalgunosdenosotrosescribirprogramasdecomputadorasesunjuegofascinanteUnprogramaesunconstruccioacutendelpensamientoNotienecostoconstruirlonopesanadaycrecefaacutecilmentebajonuestrasmanostecleando

PerosinotenemoscuidadoeltamantildeoylacomplejidaddeunprogramasesaldraacutendecontrolconfundiendoinclusoalapersonaquelocreoacuteMantenerlosprogramasbajocontroleselprincipalproblemadelaprogramacioacutenCuandofuncionaneshermosoElartedeprogramareslahabilidaddecontrolarlacomplejidadUngranprogramaestaacutedominadohechosimpleensucomplejidad

MuchosprogramadorescreenqueestacomplejidadesmejorcontroladausandosoacutelounpequentildeoconjuntodeteacutecnicasbienentendidasensusprogramasEstoshancompuestoreglasestrictas(ldquomejorespraacutecticasrdquo)queprescribenlaformaquelosprogramasdeberiacuteantenerylosmaacutescelososdeellosconsideraraacutenaaquellosquesesalendeestapequentildeazonaseguracomomalosprogramadores

iexclQueacutehostilidadhacialariquezadelaprogramacioacutenladetratardereducirlaaalgosimpleypredecibletratardehacertabuacuteatodoslosprogramasextrantildeosybellosElpanoramadetodaslasteacutecnicasdeprogramacioacutenesenormefascinanteensudiversidadypermaneceinexploradoengranparteCiertamenteespeligrosoiraseduciendoalprogramadornovatocontodotipodeconfusionesperoesosoacutelosignificaquedebesdeandarconcuidadoyestaralertaConformevayasaprendiendosiemprehabraacutenuevosretosynuevoterritorioporexplorarLosprogramadoresquesenieguenaexplorardejaraacutendeprogresarolvidaraacutensualegriacuteayseaburriraacutenconsutrabajo

Porqueacuteellenguajeimporta

EnelprincipiocuandonacioacutelacomputacioacutennohabiacutealenguajesdeprogramacioacutenLosprogrmasluciacuteanalgoasiacute

001100010000000000000000001100010000000100000001001100110000000100000010010100010000101100000010001000100000001000001000010000110000000100000000010000010000000100000001000100000000001000000000011000100000000000000000

Introduccioacuten

5

Esoesunprogramaparasumarlosnuacutemerosdel1al10eimprimirelresultado1+2++10=55PodriacuteacorrerenunasimplehipoteacuteticamaacutequinaParaprogramarlasprimerascomputadoraseranecesarioconfigurargrandesconjuntosdeinterruptoresenlaposicioacutencorrectaoperforartirasdetarjetaseintroducirlasenlacomputadoraProbablementetepuedesimaginarcuantediosoypropensoalerroreraesteprocedimientoInclusoescribirprogramassimplesrequeriacuteagraninteligenciaydisciplinaLosprogramascomplejoserancasiinconcebibles

Clarointroducirmanualmenteestososcurospatronesdebits(losunosyceros)dieronalprogramadorunprofundosentimientodeserunpoderosomagoYesohavalidoalgoenteacuterminosdesatisfaccioacuteneneltrabajo

CadaliacuteneadelprogramaanteriorcontieneunainstruccioacutenPodriacuteaserescritaenespantildeolcomosigue

1 Guardaelnuacutemero0enladireccioacutendememoria02 Guardaelnuacutemero1enladireccioacutendememoria13 Guardaelvalordeladireccioacutendememoria1enladireccioacuten24 Resta11delvalorenladireccioacutendememoria25 Sielvalorenladireccioacutendememoria2eselnuacutemero0continuacuteaconlainstruccioacuten96 Sumaelvalordeladireccioacutendememoria1alvalordeladireccioacutendememoria07 Suma1alvalordeladireccioacutendememoria18 Continuacuteaconlainstruccioacuten39 Devuelveelvalordeladireccioacutendememoria0

AunqueesoesmaacuteslegiblequeunasopadebitssiguesinseragradablePodriacuteaayudarusarnombresenlosnuacutemerosparalasinstruccionesydireccionesdememoria

Ponldquototalrdquoiguala0Ponldquoconteordquoiguala1[bucle]PonldquocomparacioacutenrdquoigualaldquoconteordquoResta11deldquocomparacioacutenrdquoSildquocomparacioacutenrdquoescerocontinuacuteaen[final]SumaldquoconteordquoaldquototalrdquoSuma1aldquoconteordquoContinuacuteaen[bucle][final]Devuelveldquototalrdquo

Introduccioacuten

6

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

IntroduccioacutenEstelibrotratadecomohacerquelascomputadorashaganloquetuacutequieresquehaganLascomputadorassontancomunescomolosdesatornilladoreshoyendiacuteaperotienenmuchamaacutescomplejidadocultayporlotantosonmaacutesdifiacutecilesdeoperaryentenderParamuchossiguensiendocosasextrantildeasunpocoamenazadoras

HemosencontradodosformasefectivasdecerrarlabrechaentenosotrossuavesorganismosbioloacutegicoscontalentoparaelrazonamientosocialyespacialylascomputadorasmanipuladorassinsentimientosdedatossinsentidoLaprimeraesusarnuestrossentidosdelmundofiacutesicoyconstruirinterfacesqueimitanesemundoynospermitenmanipularfigurasenunapantallaconnuestrosdedosEstofuncionamuybienparainteraccionescasualesconlamaacutequina

PeroauacutennohemosencontradounabuenaformadeusarlainterfazgraacuteficaparacomunicaralacomputadoracosasqueeldisentildeadordeinterfacesnoanticipoacuteParainterfacesabiertascomoindicarlealacomputadoraqueejecutetareasarbitrariashemostenidomaacutessuerteconotraestrategiaquehaceusodenuestrotalentoparaellenguajeensentildearlealacomputadorauno

LoslenguajeshumanospermitenquepalabrasyfrasessecombinenenmuchasdiferentesformaslocuaacutelnospermitedecirunaampliavariedaddecosasLoslenguajescomputacionalesaunquesongramaticalmentemenosflexiblessiguenunprincipiosimilar

Lacomputacioacutencasualsehaextendidomuchoenlosuacuteltimos20antildeosylasinterfacesbasadasenellenguajequealgunavezfueronlaformapredeterminadaenlaquelaspersonasinteractuabanconlascomputadorashansidoreemplazadasengranmedidaporinterfacesgraacuteficasPerotodaviacuteaestaacutenahiacutesisabesdondebuscarUnodeestoslenguajesJavaScriptestaacutepresenteencasitodoslosnavegadoreswebexistentesyporlotantodisponibleenpraacutecticamentetodoslosdispositivosdeconsumo

Introduccioacuten

3

Estelibrotratadehacerquetefamiliariceslosuficienteconestelenguajeparaquepuedashacerquelacomputadorahagaloquetuacutequieras

EnlaProgramacioacuten

NoiluminoaaquellosquenoestaacutendeseososdeaprendertampocodespiertoaquienesnoestaacutenansiososdedarseunaexplicacioacutenasiacutemismosSileshepresentadounaesquinadelcuadroyellosnovienenconlasotrastresnodeberiacutearecorrerotravezlospuntosConfucio

ApartedeexplicarJavaScriptteintroducireacuteenlosprincipiosbaacutesicosdelaprogramacioacutenProgramarresultadifiacutecilLasreglasfundamentalestiacutepicamentesonsimplesyclarasPerolosprogramascontruidossobreesasreglastiendenavolverselosuficientementecomplejosparaintroducirsuspropiasreglasymaacutescomplejidadEnciertaformaestaacutesconstruyendotupropiolaberintoypodriacuteasperderteeneacutel

HabraacuteocasionesenlasquealleerestelibrotesentiraacutesterriblementefrustradoSieresnuevoprogramandotendraacutesmuchomaterialnuevoparadigerirMuchodeestematerialdespueacutesseraacutecombinadoenformasquerequeriraacutenquehagasconexionesadicionales

EsturesponsabilidadrealizarelesfuerzonecesarioCuandosetehagadifiacutecilseguirestelibronoconcluyasraacutepidamentenadaacercadetuscapacidadesTueresbuenomdashsoacutelonecesitasmantenerelpasoTomaunrespirovuelvealeerelmaterialysiempreaseguacuteratedeleeryentenderlosprogramasdeejemploylosejerciciosAprenderesuntrabajoduroperotodoloqueaprendasahoraestuyoyharaacuteelaprendizajecadavezmaacutesfaacutecil

ElprogramadordecomputadoraseselcreadordeuniversosdeloscualeseacutelsoacuteloesresponsableUniversosdecomplejidadvirtualmenteilimitadapuedensercreadosenlaformadeprogramasdecomputadora

JosephWeizenbaumComputerPowerandHumanReason

UnprogramaesmuchascosasEsunapiezadetextoescritaporunprogramadoreslafuerzaquedirijealacomputadoraparahacerloquehacesondatosenlamemoriadelacomputadorayauacutenasiacutecontrolalasaccionesrealizadasenestamismamemoriaLasanalogiacuteasquetratandecompararalascomputadorasconobjetosqueconocemostiendenaquedarsecortasUnaqueseajustasuperficialmenteeslademaacutequinaunmontoacutendepiezasseparadasqueserelacionanyparahacerlofuncionartenemosqueconsiderarlasformasenqueesaspiezasseinterconectanycontribuyenalfuncionamientodeltodo

UnacomputadoraesunamaacutequinaqueactuacomoanfitrionadeestasmaacutequinasinmaterialesLascomputadorasporsiacutemismassoacutelopuedenhacercosasestuacutepidamentesimplesLarazoacutenporlaquesontanpoderosasesquehacenesascosasaunavelocidad

Introduccioacuten

4

increiacuteblementeraacutepidaUnprogramapuedecombinaringeniosamenteunnuacutemeroenormedeesasaccionessimplesparalograrcosasmuycomplicadas

ParaalgunosdenosotrosescribirprogramasdecomputadorasesunjuegofascinanteUnprogramaesunconstruccioacutendelpensamientoNotienecostoconstruirlonopesanadaycrecefaacutecilmentebajonuestrasmanostecleando

PerosinotenemoscuidadoeltamantildeoylacomplejidaddeunprogramasesaldraacutendecontrolconfundiendoinclusoalapersonaquelocreoacuteMantenerlosprogramasbajocontroleselprincipalproblemadelaprogramacioacutenCuandofuncionaneshermosoElartedeprogramareslahabilidaddecontrolarlacomplejidadUngranprogramaestaacutedominadohechosimpleensucomplejidad

MuchosprogramadorescreenqueestacomplejidadesmejorcontroladausandosoacutelounpequentildeoconjuntodeteacutecnicasbienentendidasensusprogramasEstoshancompuestoreglasestrictas(ldquomejorespraacutecticasrdquo)queprescribenlaformaquelosprogramasdeberiacuteantenerylosmaacutescelososdeellosconsideraraacutenaaquellosquesesalendeestapequentildeazonaseguracomomalosprogramadores

iexclQueacutehostilidadhacialariquezadelaprogramacioacutenladetratardereducirlaaalgosimpleypredecibletratardehacertabuacuteatodoslosprogramasextrantildeosybellosElpanoramadetodaslasteacutecnicasdeprogramacioacutenesenormefascinanteensudiversidadypermaneceinexploradoengranparteCiertamenteespeligrosoiraseduciendoalprogramadornovatocontodotipodeconfusionesperoesosoacutelosignificaquedebesdeandarconcuidadoyestaralertaConformevayasaprendiendosiemprehabraacutenuevosretosynuevoterritorioporexplorarLosprogramadoresquesenieguenaexplorardejaraacutendeprogresarolvidaraacutensualegriacuteayseaburriraacutenconsutrabajo

Porqueacuteellenguajeimporta

EnelprincipiocuandonacioacutelacomputacioacutennohabiacutealenguajesdeprogramacioacutenLosprogrmasluciacuteanalgoasiacute

001100010000000000000000001100010000000100000001001100110000000100000010010100010000101100000010001000100000001000001000010000110000000100000000010000010000000100000001000100000000001000000000011000100000000000000000

Introduccioacuten

5

Esoesunprogramaparasumarlosnuacutemerosdel1al10eimprimirelresultado1+2++10=55PodriacuteacorrerenunasimplehipoteacuteticamaacutequinaParaprogramarlasprimerascomputadoraseranecesarioconfigurargrandesconjuntosdeinterruptoresenlaposicioacutencorrectaoperforartirasdetarjetaseintroducirlasenlacomputadoraProbablementetepuedesimaginarcuantediosoypropensoalerroreraesteprocedimientoInclusoescribirprogramassimplesrequeriacuteagraninteligenciaydisciplinaLosprogramascomplejoserancasiinconcebibles

Clarointroducirmanualmenteestososcurospatronesdebits(losunosyceros)dieronalprogramadorunprofundosentimientodeserunpoderosomagoYesohavalidoalgoenteacuterminosdesatisfaccioacuteneneltrabajo

CadaliacuteneadelprogramaanteriorcontieneunainstruccioacutenPodriacuteaserescritaenespantildeolcomosigue

1 Guardaelnuacutemero0enladireccioacutendememoria02 Guardaelnuacutemero1enladireccioacutendememoria13 Guardaelvalordeladireccioacutendememoria1enladireccioacuten24 Resta11delvalorenladireccioacutendememoria25 Sielvalorenladireccioacutendememoria2eselnuacutemero0continuacuteaconlainstruccioacuten96 Sumaelvalordeladireccioacutendememoria1alvalordeladireccioacutendememoria07 Suma1alvalordeladireccioacutendememoria18 Continuacuteaconlainstruccioacuten39 Devuelveelvalordeladireccioacutendememoria0

AunqueesoesmaacuteslegiblequeunasopadebitssiguesinseragradablePodriacuteaayudarusarnombresenlosnuacutemerosparalasinstruccionesydireccionesdememoria

Ponldquototalrdquoiguala0Ponldquoconteordquoiguala1[bucle]PonldquocomparacioacutenrdquoigualaldquoconteordquoResta11deldquocomparacioacutenrdquoSildquocomparacioacutenrdquoescerocontinuacuteaen[final]SumaldquoconteordquoaldquototalrdquoSuma1aldquoconteordquoContinuacuteaen[bucle][final]Devuelveldquototalrdquo

Introduccioacuten

6

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

Estelibrotratadehacerquetefamiliariceslosuficienteconestelenguajeparaquepuedashacerquelacomputadorahagaloquetuacutequieras

EnlaProgramacioacuten

NoiluminoaaquellosquenoestaacutendeseososdeaprendertampocodespiertoaquienesnoestaacutenansiososdedarseunaexplicacioacutenasiacutemismosSileshepresentadounaesquinadelcuadroyellosnovienenconlasotrastresnodeberiacutearecorrerotravezlospuntosConfucio

ApartedeexplicarJavaScriptteintroducireacuteenlosprincipiosbaacutesicosdelaprogramacioacutenProgramarresultadifiacutecilLasreglasfundamentalestiacutepicamentesonsimplesyclarasPerolosprogramascontruidossobreesasreglastiendenavolverselosuficientementecomplejosparaintroducirsuspropiasreglasymaacutescomplejidadEnciertaformaestaacutesconstruyendotupropiolaberintoypodriacuteasperderteeneacutel

HabraacuteocasionesenlasquealleerestelibrotesentiraacutesterriblementefrustradoSieresnuevoprogramandotendraacutesmuchomaterialnuevoparadigerirMuchodeestematerialdespueacutesseraacutecombinadoenformasquerequeriraacutenquehagasconexionesadicionales

EsturesponsabilidadrealizarelesfuerzonecesarioCuandosetehagadifiacutecilseguirestelibronoconcluyasraacutepidamentenadaacercadetuscapacidadesTueresbuenomdashsoacutelonecesitasmantenerelpasoTomaunrespirovuelvealeerelmaterialysiempreaseguacuteratedeleeryentenderlosprogramasdeejemploylosejerciciosAprenderesuntrabajoduroperotodoloqueaprendasahoraestuyoyharaacuteelaprendizajecadavezmaacutesfaacutecil

ElprogramadordecomputadoraseselcreadordeuniversosdeloscualeseacutelsoacuteloesresponsableUniversosdecomplejidadvirtualmenteilimitadapuedensercreadosenlaformadeprogramasdecomputadora

JosephWeizenbaumComputerPowerandHumanReason

UnprogramaesmuchascosasEsunapiezadetextoescritaporunprogramadoreslafuerzaquedirijealacomputadoraparahacerloquehacesondatosenlamemoriadelacomputadorayauacutenasiacutecontrolalasaccionesrealizadasenestamismamemoriaLasanalogiacuteasquetratandecompararalascomputadorasconobjetosqueconocemostiendenaquedarsecortasUnaqueseajustasuperficialmenteeslademaacutequinaunmontoacutendepiezasseparadasqueserelacionanyparahacerlofuncionartenemosqueconsiderarlasformasenqueesaspiezasseinterconectanycontribuyenalfuncionamientodeltodo

UnacomputadoraesunamaacutequinaqueactuacomoanfitrionadeestasmaacutequinasinmaterialesLascomputadorasporsiacutemismassoacutelopuedenhacercosasestuacutepidamentesimplesLarazoacutenporlaquesontanpoderosasesquehacenesascosasaunavelocidad

Introduccioacuten

4

increiacuteblementeraacutepidaUnprogramapuedecombinaringeniosamenteunnuacutemeroenormedeesasaccionessimplesparalograrcosasmuycomplicadas

ParaalgunosdenosotrosescribirprogramasdecomputadorasesunjuegofascinanteUnprogramaesunconstruccioacutendelpensamientoNotienecostoconstruirlonopesanadaycrecefaacutecilmentebajonuestrasmanostecleando

PerosinotenemoscuidadoeltamantildeoylacomplejidaddeunprogramasesaldraacutendecontrolconfundiendoinclusoalapersonaquelocreoacuteMantenerlosprogramasbajocontroleselprincipalproblemadelaprogramacioacutenCuandofuncionaneshermosoElartedeprogramareslahabilidaddecontrolarlacomplejidadUngranprogramaestaacutedominadohechosimpleensucomplejidad

MuchosprogramadorescreenqueestacomplejidadesmejorcontroladausandosoacutelounpequentildeoconjuntodeteacutecnicasbienentendidasensusprogramasEstoshancompuestoreglasestrictas(ldquomejorespraacutecticasrdquo)queprescribenlaformaquelosprogramasdeberiacuteantenerylosmaacutescelososdeellosconsideraraacutenaaquellosquesesalendeestapequentildeazonaseguracomomalosprogramadores

iexclQueacutehostilidadhacialariquezadelaprogramacioacutenladetratardereducirlaaalgosimpleypredecibletratardehacertabuacuteatodoslosprogramasextrantildeosybellosElpanoramadetodaslasteacutecnicasdeprogramacioacutenesenormefascinanteensudiversidadypermaneceinexploradoengranparteCiertamenteespeligrosoiraseduciendoalprogramadornovatocontodotipodeconfusionesperoesosoacutelosignificaquedebesdeandarconcuidadoyestaralertaConformevayasaprendiendosiemprehabraacutenuevosretosynuevoterritorioporexplorarLosprogramadoresquesenieguenaexplorardejaraacutendeprogresarolvidaraacutensualegriacuteayseaburriraacutenconsutrabajo

Porqueacuteellenguajeimporta

EnelprincipiocuandonacioacutelacomputacioacutennohabiacutealenguajesdeprogramacioacutenLosprogrmasluciacuteanalgoasiacute

001100010000000000000000001100010000000100000001001100110000000100000010010100010000101100000010001000100000001000001000010000110000000100000000010000010000000100000001000100000000001000000000011000100000000000000000

Introduccioacuten

5

Esoesunprogramaparasumarlosnuacutemerosdel1al10eimprimirelresultado1+2++10=55PodriacuteacorrerenunasimplehipoteacuteticamaacutequinaParaprogramarlasprimerascomputadoraseranecesarioconfigurargrandesconjuntosdeinterruptoresenlaposicioacutencorrectaoperforartirasdetarjetaseintroducirlasenlacomputadoraProbablementetepuedesimaginarcuantediosoypropensoalerroreraesteprocedimientoInclusoescribirprogramassimplesrequeriacuteagraninteligenciaydisciplinaLosprogramascomplejoserancasiinconcebibles

Clarointroducirmanualmenteestososcurospatronesdebits(losunosyceros)dieronalprogramadorunprofundosentimientodeserunpoderosomagoYesohavalidoalgoenteacuterminosdesatisfaccioacuteneneltrabajo

CadaliacuteneadelprogramaanteriorcontieneunainstruccioacutenPodriacuteaserescritaenespantildeolcomosigue

1 Guardaelnuacutemero0enladireccioacutendememoria02 Guardaelnuacutemero1enladireccioacutendememoria13 Guardaelvalordeladireccioacutendememoria1enladireccioacuten24 Resta11delvalorenladireccioacutendememoria25 Sielvalorenladireccioacutendememoria2eselnuacutemero0continuacuteaconlainstruccioacuten96 Sumaelvalordeladireccioacutendememoria1alvalordeladireccioacutendememoria07 Suma1alvalordeladireccioacutendememoria18 Continuacuteaconlainstruccioacuten39 Devuelveelvalordeladireccioacutendememoria0

AunqueesoesmaacuteslegiblequeunasopadebitssiguesinseragradablePodriacuteaayudarusarnombresenlosnuacutemerosparalasinstruccionesydireccionesdememoria

Ponldquototalrdquoiguala0Ponldquoconteordquoiguala1[bucle]PonldquocomparacioacutenrdquoigualaldquoconteordquoResta11deldquocomparacioacutenrdquoSildquocomparacioacutenrdquoescerocontinuacuteaen[final]SumaldquoconteordquoaldquototalrdquoSuma1aldquoconteordquoContinuacuteaen[bucle][final]Devuelveldquototalrdquo

Introduccioacuten

6

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

increiacuteblementeraacutepidaUnprogramapuedecombinaringeniosamenteunnuacutemeroenormedeesasaccionessimplesparalograrcosasmuycomplicadas

ParaalgunosdenosotrosescribirprogramasdecomputadorasesunjuegofascinanteUnprogramaesunconstruccioacutendelpensamientoNotienecostoconstruirlonopesanadaycrecefaacutecilmentebajonuestrasmanostecleando

PerosinotenemoscuidadoeltamantildeoylacomplejidaddeunprogramasesaldraacutendecontrolconfundiendoinclusoalapersonaquelocreoacuteMantenerlosprogramasbajocontroleselprincipalproblemadelaprogramacioacutenCuandofuncionaneshermosoElartedeprogramareslahabilidaddecontrolarlacomplejidadUngranprogramaestaacutedominadohechosimpleensucomplejidad

MuchosprogramadorescreenqueestacomplejidadesmejorcontroladausandosoacutelounpequentildeoconjuntodeteacutecnicasbienentendidasensusprogramasEstoshancompuestoreglasestrictas(ldquomejorespraacutecticasrdquo)queprescribenlaformaquelosprogramasdeberiacuteantenerylosmaacutescelososdeellosconsideraraacutenaaquellosquesesalendeestapequentildeazonaseguracomomalosprogramadores

iexclQueacutehostilidadhacialariquezadelaprogramacioacutenladetratardereducirlaaalgosimpleypredecibletratardehacertabuacuteatodoslosprogramasextrantildeosybellosElpanoramadetodaslasteacutecnicasdeprogramacioacutenesenormefascinanteensudiversidadypermaneceinexploradoengranparteCiertamenteespeligrosoiraseduciendoalprogramadornovatocontodotipodeconfusionesperoesosoacutelosignificaquedebesdeandarconcuidadoyestaralertaConformevayasaprendiendosiemprehabraacutenuevosretosynuevoterritorioporexplorarLosprogramadoresquesenieguenaexplorardejaraacutendeprogresarolvidaraacutensualegriacuteayseaburriraacutenconsutrabajo

Porqueacuteellenguajeimporta

EnelprincipiocuandonacioacutelacomputacioacutennohabiacutealenguajesdeprogramacioacutenLosprogrmasluciacuteanalgoasiacute

001100010000000000000000001100010000000100000001001100110000000100000010010100010000101100000010001000100000001000001000010000110000000100000000010000010000000100000001000100000000001000000000011000100000000000000000

Introduccioacuten

5

Esoesunprogramaparasumarlosnuacutemerosdel1al10eimprimirelresultado1+2++10=55PodriacuteacorrerenunasimplehipoteacuteticamaacutequinaParaprogramarlasprimerascomputadoraseranecesarioconfigurargrandesconjuntosdeinterruptoresenlaposicioacutencorrectaoperforartirasdetarjetaseintroducirlasenlacomputadoraProbablementetepuedesimaginarcuantediosoypropensoalerroreraesteprocedimientoInclusoescribirprogramassimplesrequeriacuteagraninteligenciaydisciplinaLosprogramascomplejoserancasiinconcebibles

Clarointroducirmanualmenteestososcurospatronesdebits(losunosyceros)dieronalprogramadorunprofundosentimientodeserunpoderosomagoYesohavalidoalgoenteacuterminosdesatisfaccioacuteneneltrabajo

CadaliacuteneadelprogramaanteriorcontieneunainstruccioacutenPodriacuteaserescritaenespantildeolcomosigue

1 Guardaelnuacutemero0enladireccioacutendememoria02 Guardaelnuacutemero1enladireccioacutendememoria13 Guardaelvalordeladireccioacutendememoria1enladireccioacuten24 Resta11delvalorenladireccioacutendememoria25 Sielvalorenladireccioacutendememoria2eselnuacutemero0continuacuteaconlainstruccioacuten96 Sumaelvalordeladireccioacutendememoria1alvalordeladireccioacutendememoria07 Suma1alvalordeladireccioacutendememoria18 Continuacuteaconlainstruccioacuten39 Devuelveelvalordeladireccioacutendememoria0

AunqueesoesmaacuteslegiblequeunasopadebitssiguesinseragradablePodriacuteaayudarusarnombresenlosnuacutemerosparalasinstruccionesydireccionesdememoria

Ponldquototalrdquoiguala0Ponldquoconteordquoiguala1[bucle]PonldquocomparacioacutenrdquoigualaldquoconteordquoResta11deldquocomparacioacutenrdquoSildquocomparacioacutenrdquoescerocontinuacuteaen[final]SumaldquoconteordquoaldquototalrdquoSuma1aldquoconteordquoContinuacuteaen[bucle][final]Devuelveldquototalrdquo

Introduccioacuten

6

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

Esoesunprogramaparasumarlosnuacutemerosdel1al10eimprimirelresultado1+2++10=55PodriacuteacorrerenunasimplehipoteacuteticamaacutequinaParaprogramarlasprimerascomputadoraseranecesarioconfigurargrandesconjuntosdeinterruptoresenlaposicioacutencorrectaoperforartirasdetarjetaseintroducirlasenlacomputadoraProbablementetepuedesimaginarcuantediosoypropensoalerroreraesteprocedimientoInclusoescribirprogramassimplesrequeriacuteagraninteligenciaydisciplinaLosprogramascomplejoserancasiinconcebibles

Clarointroducirmanualmenteestososcurospatronesdebits(losunosyceros)dieronalprogramadorunprofundosentimientodeserunpoderosomagoYesohavalidoalgoenteacuterminosdesatisfaccioacuteneneltrabajo

CadaliacuteneadelprogramaanteriorcontieneunainstruccioacutenPodriacuteaserescritaenespantildeolcomosigue

1 Guardaelnuacutemero0enladireccioacutendememoria02 Guardaelnuacutemero1enladireccioacutendememoria13 Guardaelvalordeladireccioacutendememoria1enladireccioacuten24 Resta11delvalorenladireccioacutendememoria25 Sielvalorenladireccioacutendememoria2eselnuacutemero0continuacuteaconlainstruccioacuten96 Sumaelvalordeladireccioacutendememoria1alvalordeladireccioacutendememoria07 Suma1alvalordeladireccioacutendememoria18 Continuacuteaconlainstruccioacuten39 Devuelveelvalordeladireccioacutendememoria0

AunqueesoesmaacuteslegiblequeunasopadebitssiguesinseragradablePodriacuteaayudarusarnombresenlosnuacutemerosparalasinstruccionesydireccionesdememoria

Ponldquototalrdquoiguala0Ponldquoconteordquoiguala1[bucle]PonldquocomparacioacutenrdquoigualaldquoconteordquoResta11deldquocomparacioacutenrdquoSildquocomparacioacutenrdquoescerocontinuacuteaen[final]SumaldquoconteordquoaldquototalrdquoSuma1aldquoconteordquoContinuacuteaen[bucle][final]Devuelveldquototalrdquo

Introduccioacuten

6

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

iquestPuedesentendercoacutemofuncionaelprogramaenestepuntoLasprimerasdosliacuteneasponenendoslocacionesdememoriasusvaloresinicialestotalseraacuteusadoparaconstruirelresultadodelcaacutelculoyconteomantendraacuteelregistrodelnuacutemeroenelqueestamostrabajandoenestemomentoLasliacuteneasqueusancomparacioacutensonprobablementelasmaacutesrarasElprogramaquiereversiconteoesiguala11parasabersipuedeterminarAcausadequenuestramaacutequinahipoteacuteticaesmaacutesbienprimitivasolopuedeprobarsiunnuacutemeroesceroytomarunadecisioacuten(osalto)basadaenesoAsiacutequeusaladireccioacutendememoriaetiquetadacomocomparacioacutenparacalcularelvalordeconteo-11ytomaunadecisioacutenbasadaenesevalorLasproacuteximasdosliacuteneassumanelvalordeconteoalresultadoeincrementanconteoen1cadavezqueelprogramahadecidoqueconteonoestodaviacutea11

EsteeselmismoprogramaenJavaScript

vartotal=0varconteo=1while(conteolt=10)total+=conteoconteo+=1consolelog(total)rarr55

EjemploCodepen

EstaversioacutennosdaunascuantasmejorasmaacutesYlomaacutesimportanteesqueyanohaynecesidaddeespecificarlaformaenquequeremosquenuestroprogramasaltedeatraacutesparaadelanteElconstructordellenguajewhileseencargadeesoContinuacuteaejecutaacutendoelbloque(dentrodelasllaves)debajodeeacutelmientraslacondicioacutenqueselediosemantengaEsacondicioacutenesconteolt=10loquesignificaconteoesmenoroigualque10Yanotenemosquecrearunvalortemporalycompararlocon0locuaacuteleraundetallesinintereacutesparanosotrosPartedelpoderdeloslenguajesdeprogramacioacutenesqueestosseencargandelosdetallesquenonosinteresan

Alfinaldelprogramadespueacutesdequelaconstruccioacutenwhilehaterminadolaoperacioacutenconsolelogesaplicadaalresultadoparaimprimirlocomoresultado

Finalmenteasiacuteescomoelprogramaluciriacuteasisucedieraquetenemoslasconvenientesoperacionesrangeysumdisponiblesunacreaunacoleccioacutendenuacutemerosdentrodeunrangoylaotracalculalasumadeunacoleccioacutendenuacutemerosrespectivamente

consolelog(sum(range(110)))rarr55

Introduccioacuten

7

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

LamoralejadeestahistoriaesqueelmismoprogramapuedeserexpresadoenformaslargascortaslegibleseilegiblesLaprimeraversioacutendelprogramaeraextremadamentedifiacutecildeentendermientrasquelauacuteltimaestaacutecasienlenguajeingleslog(registra)lasum(suma)delrangodenuacutemerosdel1al10Veremosencapiacutetulosposteriorescomoconstruiroperacionescomosumyrange)

UnbuenlenguajedeprogramacioacutenayudaalprogramadoralpermitirlehablaracercadelasaccionesquelacomputadoratienequerealizarenunnivelmaacutesaltoAyudaaomitirdetallesquenonosinteresanproveeconvenientesbloquesdeconstruccioacuten(talescomowhileyconsolelog)ytepermitedefinirtuspropiosbloques(comosumyrange)yhacefaacutecilcomponeresosbloques

iquestQueacuteesJavaScript

JavaScriptfueintroducidoen1995comounaformadeantildeadirprogramasalaspaacuteginaswebenelnavegadorNetscapeNavigatorDesdeentoncesellenguajehasidoadoptadoporlamayoriacuteadelosnavegadoresmaacutesimportantesHahechoposibleslasaplicacioneswebmodernasaplicacionesconlasquepuedesinteractuardirectamentesinhacerrecargadelapaacuteginaparacadaaccioacutenPerotambieacutenesusadoensitioswebmaacutestradicionalesparaantildeadirlesdistintasformasdeinteractividadyhacerlosmaacutesingeniosos

EsimportanteentenderqueJavaScriptnotienecasinadaqueverconellenguajedeprogramacioacutenllamadoJavaElnombretanparecidofueinspiradoporrazonesdemarketingmaacutesquedebuenjuicioCuandoJavaScriptestabaempezandoellenguajeJavaestabasiendopromovidofuertementeyganandopopularidadAlguienpensoacutequeseriacuteabuenaideacolgarsedesueacutexitoAhorayanosquedamosconelnombre

DespueacutesdesuadopcioacutenfueradeNetscapeundocumentodeestaacutendarfueescritoparadescribirlaformaenqueJavaScriptdeberiacuteadetrabajarparaasegurarsedequedistintosprogramasqueargumentabansoportarJavaScripthablaranrealmentedelmismolenguajeEstedocumentoesllamadoelestaacutendarECMAScriptenhonoralaEcmaInternationalOrganizationquerealizoacutelaestandarizacioacutenEnlapraacutecticalosteacuterminosECMAScriptyJavaScriptpuedenserusadosindistintamentesondosnombresparaelmismolenguaje

ExistenaquellosquediraacutencosasterriblesacercadeJavaScriptMuchasdeesascosassonciertasLaprimeravezquetuvequeprogramaralgoenJavaScriptraacutepidamentellegueacuteadespreciarloAceptabacualquiercosaqueyoescribieraperolainterpretabaenunaformacompletamentedistintaaloqueyoqueriacuteadecirEstoteniacuteamuchoqueverconelhechodequeyonoteniacuteaideadeloqueestabahaciendoporsupuestoperoaquiacuteexisteunproblemarealJavaScriptesextremadamenteliberalenloquepermiteLaideadetraacutesdeestedisentildeo

Introduccioacuten

8

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica

esquehariacutealaprogramacioacutenenJavaScriptmaacutesfaacutecilparalosprincipiantesEnrealidadlamayorpartedelasvecesesohacemaacutesdifiacutecilencontrarloserroresentusprogramasdebidoaqueelsistemanotelossentildealaraacute

EstaflexibilidadtienesusventajastambieacutenPermitemuchasteacutecnicasquesonimposiblesenotroslenguajesmaacutesriacutegidosycomoveraacutespuedeserusadaparasuperaralgunasdelasfallasdeJavaScript(porejemploenelCapiacutetulo10)DespueacutesdeaprenderellenguajepropiamenteydetrabajarconeacutelporuntiempoJavaScriptrealmentemehagustado

HanexistidovariasversionesdeJavaScriptECMAScriptversioacuten3fuelaversioacutenampliamentesoportadaenlaeacutepocadeascencioacutenaladominacioacutendeJavaScriptmaacutesomenosentre2000y2010Duranteestetiempoeltrabajofuedirigidoaunaambiciosaversioacuten4queplaneabavariasmejorasradicalesyextensionesallenguajeCambiarunlenguajevivoampliamenteusadoenunaformatanradicalresultoacuteserpoliacuteticamentedifiacutecilyeltrabajoenlaversioacuten4fueabandonadoen2008llevandoasiacutealasalidadelamuchomenosambiciosaversioacuten5en2009Nosotrosestamosenelpuntoenelquetodoslosnavegadoresmayoressoportanlaversioacuten5queeslaversioacutenenlaqueestelibroseenfocaraacuteLaversioacuten6estaacuteenprocesodeserterminadayalgunosnavegadoresestaacutenempezandoasoportarnuevascaracteriacutesticasdeestaversioacuten

LosnavegadoreswebnosonlasuacutenicasplataformasenlasqueJavaScriptesusadoAlgunasBasesdeDatoscomoMongoDByCouchDBusanJavaScriptcomosulenguajedemanejoyconsultaVariasplataformasparaprogramacioacutendecomputadorasdeescritorioyservidoresmaacutesnotablementeelproyectoNodejs(eltemadelCapiacutetulo20)estaacutenhaciendodisponibleunentornopoderosoparalaprogramacioacutenenJavaScriptfueradelnavegador

Coacutedigoyqueacutehacerconeacutel

ElcoacutedigoeseltextodelqueestaacutencompuestoslosprogramasLamayorpartedeloscapiacutetulosdeestelibrocontienenunmontoacutendeeacutelEnmiexperiencialeeryescribircoacutedigosonpartesindispensablesdeaprenderaprogramarasiacutequetratadenosoacutelodarlesunamiradaraacutepidaalosejemplosLeacuteelosateacutentamenteyentieacutendelosEstopodriacuteaserlentoyconfusoalprincipioperoprometoqueraacutepidamentelosentenderasLomismoesaplicablealosejerciciosNoasumasquelosentiendeshastaquerealementehayasescritounasolucioacutenquefuncione

TerecomiendoprobartussolucionesalosejerciciosenuninteacuterpretedeJavaScriptrealDeesaformaobtendraacutesretroalimentacioacuteninmediataacercadesiloqueestaacuteshaciendofuncionayesperoseastentadoaexperimentareirmaacutesallaacutesdelosejercicios

Introduccioacuten

9

LamaneramaacutesfaacutecildecorrerelcoacutedigodellibroydeexperimentarconeacutelesenlaversioacutenwebenhttpeloquentjavascriptnetAhiacutepodraacuteshacerclickenunejemploparaeditarloycorrerloyparaverlasalidaqueproduceParatrabajarenloejerciciosdiriacutegeteahttpeloquentjavascriptnetqueprovecoacutedigoparaempezarconcadaejercicioytepermiteverlassoluciones

SiquierescorrerlosprogramasdeestelibrofueradelambientequeseproveehayqueprestarleatencioacutenaciertascosasMuchosejemplosdeberiacuteantrabajarporsiacutemismosPeroelcoacutedigodeloscapiacutetulosmaacutesavanzadosestaacuteescritoparaunentornoespeciacutefico(elnavegadoroNodejs)ysoacutelopuedecorrerahiacuteAdemaacutesmuchoscapiacutetulosdefinenprogramasmaacutesgrandesylaspartesdelcoacutedigoqueapareceneneacuteldependendeentreellasodearchivosexternosElhttpeloquentjavascriptnetcodeenelsitiotienelinksparadescargarlosarchivosZipquecontienentodoslosscriptsydatosnecesariosparahacerfuncionarelcoacutedigodecualquiercapiacutetulo

Vistageneraldellibro

EstelibroestaacutecompuestoportrespartesLosprimeros11capiacutetuloshablandeJavaScriptensiacutemismoLossiguientesochosonacercadelosnavegadoreswebylaformaenqueJavaScriptesusadoparaprogramarlosFinalmentelosuacuteltimosdoscapiacutetulosestaacutendedicadosa((Nodejs))otroentornoparaprogramarenJavaScript

AlolargodellibrohaycincocapiacutetulosdeproyectoquedescribenprogramasdeejemplomaacutesgrandesparadarteunapruebadelaprogramacioacutenenelmundorealEnorderdeaparcicioacutentrabajaremosensimulacioacutendevidaartificialunlenguajedeprogramacioacutenunjuegodeplataformaunprogramadepinturayunsitiodinaacutemico

LapartedellenguajedellibroempiezaconcuatrocapiacutetulosparapresentarlaestructurabaacutesicadeJavaScriptEstospresentanestructurasdecontrol(comolapalabrawhilequevisteenestaintroduccioacuten)funciones(escribirtuspropiasoperaciones)yestructurasdedatosDespeueacutesdeestoseraacutescapazdeescribirprogramassimplesDespueacutesloscapiacutetulos5y6presentanteacutecnicasparausarfuncionesyobjetosparaescribircoacutedigomaacutesabstractoydeestamaneramanteneralacomplejidadbajocontrol

Despueacutesdeunprimercapiacutetulodeproyectolaprimerapartedellibrocontinuacuteaconcapiacutetulosacercademanejoycorreccoacutendeerroresexpresionesregulares(unaherramientaimportanateparaelmanejodedatosdetexto)ymodularidadotraarmacontralacomplejidadElsegundocapiacutetulodeproyectoterminaconlaprimerapartedellibro

Introduccioacuten

10

EnlasegundapartelosCapiacutetulos12a19describenlasherramientasalasqueJavaScripttieneaccesoenelnavegadorwebAprenderaacutesamostrarcosasenlapantalla(Capiacutetulos13y16)repsonderalosdatosdeentradadelusuario(Capiacutetulos14y18)yacomunicarteatraveacutesdelared(Capiacutetulo17)Otravezhaydosproyectosenestaparte

DespueacutesdeesoelCapiacutetulo20describeNodejsyenelCapiacutetulo21seconstruyeunsencillosistemawebusandoesaherramienta

FinalmenteelCapiacutetulo22describealgunasdelasconsideracionesquesedebenteneraloptimizarprogramasdeJavaScriptparaqueseanraacutepidos

ConvencionesTipograacuteficas

EnestelibroeltextoescritoenfuentemonoespaciorepresentaraacuteelementosdeprogramasalgunasvecesprogramascompletosyotraspartesdeprogramasquehayansidodefinidoscercadeahiacuteLosprogramas(deloscualeshasvistounospocos)estaacutenescritoscomosigue

functionfac(n)if(n==0)return1elsereturnfac(n-1)n

Algunasvecesparamostrarlasalidaqueunprogramaproducelasalidaesperadaseraacuteescritadespueacutesdeestecondosdiagonalesyunaflechaenfrente

consolelog(fac(8))rarr40320

iexclBuenasuerte

Introduccioacuten

11

ValoresTiposyOperadoresDebajodelasuperficiedelamaacutequinaelprogramasemueveSinesfuerzoseexpandeycontraeEngranarmoniacutealoselectronesseseparanyreagrupanLasformasenelmonitornosonmaacutesqueondasenelaguaLaescenciapermaneceinvisibledebajoMasterYuan-MaTheBookofProgramming

EnelmundodelascomputadorassoacuteloexistenlosdatosPuedesleermodificarycrearnuevosdatosperocualquiercosaquenoseadatossimplementenoexisteTodosestosdatossonguardadosenlargassecuenciasdebitsyporlotantosonparecidos

LosbitssoncualquiertipodecosascondosvaloresnormalmentedescritoscomocerosyunosDentrodelacomputadoratomanformascomoaltaobajacargaeleacutectricaunasentildealdeacutebilofuerteounpuntobrillanteuopacoenlasuperficiedeunCDCualquierpiezadeinformacioacutendiscretapuedeserreducidaaunasecuenciadecerosyunosyporlotantorepresentadacomobits

Porejemplopiensacoacutemopodriacuteasrepresentarelnuacutemero13enbitsFuncionadelamismaformaenqueescribesnuacutemerosdecimalesperoenvezdetener10diacutegitostienessoacutelo2yelpesodecadaunoseincrementaporunfactorde2dederechaaizquierdaAquiacuteestaacutenlosbitsqueconformanelnuacutemero13conlospesosdecadaunomostradosdebajodeellos

000011011286432168421

Asiacutequeeseeselnuacutemerobinario00001101u8+4+1queequivalea13

Valores

ImaginaunmardebitsUnoceacuteanodeestosUnacomputadoramodernatiacutepicatienemaacutesde30milmillonesdebitsensualmacenamientodedatosvolaacutetilElalmacenamientonovolaacutetil(eldiscoduroosuequivalente)tieneunpardeoacuterdenesdemagnitudmaacutestodaviacutea

1ValoresTiposyOperadores

12

ParasercapazdetrabajarconsemejantescantidadesdebitssinperdertepuedessepararlosenpedazosquerepresentenpiezasdeinformacioacutenEnunentornoenJavaScriptesospedazossonllamadosvaloresAunquetodoslosvaloresestaacutenhechosdebitsjuegandiferentesrolesCadavalortieneuntipoquedeterminasurolExistenseistiposbaacutesicosdevaloresenJavaScriptnuacutemeroscadenasBooleanosobjetosfuncionesyvaloresindefinidos

ParacrearunvalorsoacutelotienesqueinvocarsunombreEstoesconvenienteNotienesquereuinirelmaterialdeconstruccioacutendetusvaloresopagarporellosSoacutelollamasunoywooshlotienesNosoncreadosdelanadaporsupuestoCadavalortienequeestaralmacenadoenalguacutenlugarysiquieresusarunacantidadenormedeestosalmismotiempotepodriacuteasquedarsinbitsAfortunadamenteestoseconvierteenunproblemasoacutelamentesilosnecesitastodosalmismotiempoTanprontocomodejesdeusarunvalorsedisiparaacutedejandosusbitsparaqueseanrecicladoscomomaterialdeconstruccioacutendelaproacuteximageneracioacutendevalores

EstecapiacutetulointroduceloselementosatoacutemicosdelosprogramasenJavaScriptlostiposdevaloressimplesylosoperadoresquepuedenactuarsobretalesvalores

Nuacutemeros

Losvaloresdetiponuacutemero(number)sonsinsorpresaalgunavaloresnumeacutericosEnunprogramaenJavaScriptseescribendelasiguienteforma

13

Usaesoenunprogramaycausaraacutequeelpatroacutendebitsparaelnuacutemero13existadentrodelamemoriadelacomputadora

JavaScriptusaunacantidadfijadebits64paraguardarunvalordeltiponuacutemeroExisteunliacutemiteenlacantidaddepatronesquesepuedenhacercon64bitsloquesignificaquelacantidaddenuacutemerosquepuedesrepresentartambieacuteneslimitadaParaNdiacutegitos

1ValoresTiposyOperadores

13

decimaleslacantidaddenuacutemerosquepuedenserrepresentadoses10^N^Similarmentedados64diacutegitosbinariospuedesrepresentar2^64^nuacutemerosdiferentesqueescercade18cuatrillones(un18con18cerosdespueacutes)Esoesmucho

Lamemoriadelacomputadorasoliacuteasermuchomaacutespequentildeaylagentetendiacuteaausargruposde8oacute16bitspararepresentarsusnuacutemerosErafaacutecildesbordaraccidentalmentenuacutemerostanpequentildeosterminarconunnuacutemeroquenopudieraseralmacenadoenelnuacutemerodadodebitsHoyinclusolascomputadoraspersonalestienenmuchamemoriaasiacutequeereslibredeusargruposde64bitsloquesignificaquenecesitaspreocupartedeldesbordamientosoacutelocuandoesteacutestratandoconnuacutemerosverdaderamenteastronoacutemicos

Notodoslosnuacutemeroenterosdebajode18cuatrillonescabenenunnuacutemerodeJavaScriptEsosbitstambieacutenguardannuacutemerosnegativosasiacutequeunbitindicaelsignodelnuacutemeroUnproblemamayoresquelosnuacutemerosnoenterostambieacutendebenserrepresentadosParahacerestoalgunosdelosbitssonusadosparaguardarlaposicioacutendelpuntodecimalElnuacutemeroenteromaacuteximorealquepuedeserguardadoestaacutemaacutescercadelrangodelos9trillones(15ceros)queauacutenessatisfactoriamentegrande

Losnuacutemerosfraccionariossonescritosusandounpunto

981

Paranuacutemerosmuygrandesomuypequentildeostambieacutensepuedeusarlanotacioacutencientiacuteficaantildeadiendounaedeexponenteseguidoporelexponentedelnuacutemero

2998e8

Estoes2998times10^8=299800000

Caacutelculosconnuacutemerosenteros(eningleacutesllamadosinteger)maacutespequentildeosqueelsupracitado9trillonesestaacutengarantizadosparasiempreserprecisosDesafortunadamentecaacutelculosconnuacutemerosfraccionariosgeneralmentenolosonJustocomoπ(pi)nopuedeserexpresadoprecisamenteporunnuacutemerofinitodediacutegitosdecimalesmuchosnuacutemerospierdenalgodeprecisioacutencuandosoacutelohay64bitsdisponiblesparaguardarlosEstoesunapenaperocausaproblemaspraacutecticossoacuteloenalgunassituacionesespeciacuteficasLoimportanteesestaraltantodeestoytrataralosnuacutemerosdigitalesfraccionarioscomoaproximacionesynocomovaloresprecisos

Aritmeacutetica

1ValoresTiposyOperadores

14

LoprincipalquesehaceconlosnuacutemeroseslaaritmeacuteticaLasoperacionesaritmeacuteticascomolasumaolamultiplicacioacutentomandosvaloresyproducenunonuevoapartirdeestosAsiacuteescomolucenenJavaScript

100+411

Lossiacutembolos+ysonllamadosoperadoresElprimerorepresentalasumayelsegundolamultiplicacioacutenAlponerunoperadorentredosvaloresseaplicaraacutelaoperacioacutenaesosvaloresyproduciraacuteunnuevovalor

iquestSignificaelejemploanteriorsuma4y100ymultiplicaelresultadopor11oeslamultiplicacioacutenralizadaantesdehacerlasumaComopudistehaberadivinadolamultiplicacioacutenocurreprimeroPerocomoenmatemaacuteticaspuedescambiarestomedianteencerrarenpareacutentesislasuma

(100+4)11

Paralarestaexisteeloperador-yladivisioacutensepuedehacerconeloperador

CuandolosoperadoresaparecenjuntossinpareacutentesiselordenenelquesonaplicadosesdeterminadoporsuprecedenciaElejemplomuestraquelamultiplicacioacutenseaplicaantesquelasumaEloperadortienelamismaprecedenciaqueDeigualformapasacon+y-Cuandovariosoperadoresconlamismaprecedenciaaparecenjuntoscomoen1-2+1sonaplicadosdeizquierdaaderecha(1-2)+1

EstasreglasdeprecedenciasonalgodeloquenotedeberiacuteasdepreocuparCuandotengasdudasimplementeagregapareacutentesis

ExisteunoperadoraritmeacuteticomaacutesquepodriacuteasnoreconocerinmediatamenteElsiacutemboloesusadopararepresentarlaoperacioacutensobranteXYeselsobrantededividirXentreYPorejemplo314100produce14y14412da0LaprecedenciadelsobranteeslamismaqueladelamultiplicacioacuteydivisioacutenVeraacutesamenudoesteoperadorreferidocomomoacuteduloaunqueteacutecnicamentesobranteesmaacutespreciso

NuacutemerosEspeciales

HaytresvaloresespecialesenJavaScriptquesonconsideradosnuacutemerosperonosecomportancomonuacutemerosnormales

LosprimerosdossonInfinityy-InfinityquerepresentaninfinitospositivosynegativosInfinity-1siguesiendoInfinityyasiacuteporelestiloNoconfiacuteesmuchoenloscaacutelculosbasadoseninfinitosNosonmatemaacuteticamenteconfiablesyprontotellevaraacutenal

1ValoresTiposyOperadores

15

proacuteximonuacutemeroespecialNaN

NaNsonlassiglasdeldquonotanumberrdquo(noesunnuacutemero)aunqueesunvalordeltiponuacutemeroObtendraacutesesteresultadocuandoporejemplotratesdecalcular00(ceroentrecero)Infinity-Infinityocualquierotraoperacioacutennumeacutericaquenoproduzcaunresultadoprecisosignificativo

Cadenas

ElsiguientetipodedatobaacutesicosonlascadenasEstassonusadaspararepresentartextoSondeclaradasalponerelcontenidoentrecomillas

ParchamibotecongomademascarMonkeyswavegoodbye

Tantolascomillassimplescomolasdoblespuedenserusadasparadeclararcadenasdetextomientrascoincidanalprincipioyalfinal

CasicualquiercosapuedeestarentrecomillasyJavaScriptcrearaacuteunacadenaPerounoscuantoscaracteressonunpocodifiacutecilesPuedesimaginarqueponercomillasdentrodecomillaspuedeserdifiacutecilNewlines(elcaraacutectersaltodeliacutenealoqueobtinescuandopresionasEnter)tampocopuedeserintroducidoentrecomillasLacadenatienequepermanecerenunasolaliacutenea

Parahacerposiblelainclusioacutendeestoscaracteresenunacadenadetextolasiguientenotacioacutenesusadacuandounadiagonalinvertida(backslash)seencuentradentrodeuntextoentrecomillasindicaqueelcaraacutectersiguientetieneunsignificadoespecialEstoesllamadoescaparelcaraacutecterUnacomillaqueesprecedidaporunadiagonalinvertidanoterminaraacutelacadenasinoqueseraacutepartedeellaCuandouncaraacutecternsigueaunadiagonalinvertidaseinterpretacomounanuevaliacuteneaSimilarmenteuntdespueacutesdeladiagonalinvertidasignificauntabuladorTomemoslasiguientecadena

EstaeslaprimeraliacuteneanYestalasegunda

Elverdaderotextocontenidoes

EstaeslaprimeraliacuteneaYestalasegunda

ExistenporsupuestosituacionesenlasquequerraacutesqueunadiagonalinvertidaseasoacuteloesoenunacadenadetextonouncoacutedigoespecialSidosdiagonalesinvertidasestaacutenjuntassevolveraacutenunaysoacuteloesoquedaraacutecomoresultadoenelvalordelacadenaAsiacutees

1ValoresTiposyOperadores

16

comolacadenaUncaraacutecterdenuevaliacuteneaesescritonpuedeserexpresada

Uncaraacutecterdenuevaliacuteneaesescriton

Lascadenasdetextonopuedenserdivididasnumeacutericamentemultiplicadasorestadasperoelcaraacutecter+puedeserusadoenellasNosumasinoqueconcatenapegadoscadenasLasiguienteliacuteneaproducelacadenaconcatenar

con+cat+e+nar

Haymaacutesmanerasdemanipularlascadenasdelasquehablaremoscuandolleguemosalosmeacutetodosenellink04_datahtmlmethods[Capiacutetulo4]

OperadoresUnitario

NotodoslosoperadoressonsiacutembolosAlgunossonescritoscomopalabrasUnejemploeseloperadortypeofqueproduceunacadenadetextoquerepresentaeltipodelvalorquelepasaste

consolelog(typeof45)rarrnumberconsolelog(typeofx)rarrstring

UsaremosconsolelogparaindicarquequeremosverelresultadodelaevaluacioacutendealgoCuandocorresesecoacutedigoelvalorproducidodeberiacuteamostrarseenpantallaaunquelaformaenqueaparecedependeraacutedelentornoenqueesteacutescorriendoelprograma

LosotrosoperadoresquehemosvistooperabansobredosvaloresperotypeofsoacutelamentetomaunoLosoperadoresqueusandosvaloressonllamadosoperadoresbinariosmientrasqueaquellosquesoacutelotomanunosonllamadosoperadoresunitariosEloperadormenospuedeusartantocomooperadorbinariocomooperadorunitario

consolelog(-(10-2))rarr-8

ValoresBooleanos

AmenudonecesitaraacutesunvalorquesimplementedistingaentredosposibilidadescomosiacuteynooencendidoyapagadoParaestoJavaScripttieneuntipoBooleanoquetienesoacutelodosvaloresverdadero(true)yfalso(false)quesonsimplementeestaspalabrasen

1ValoresTiposyOperadores

17

ingleacutes

Comparaciones

Estaesunaformadeproducirvaloresbooleanos

consolelog(3gt2)rarrtrueconsolelog(3lt2)rarrfalse

LossignosgtyltsonlossiacutembolostradicionalesparaesmayorqueyesmenorquerespectivamenteEstossonoperadoresbinariosAplicarlosresultaenunvalorBooleanoqueindicasisonciertosenesecaso

Lascadenasdetextopuedensercomparadasdelamismamanera

consolelog(AardvarkltZoroaster)rarrtrue

LamaneraenquelascadenassonordenadasesmaacutesomenosalfabeacuteticalasletrasmayuacutesculassonsiempremenoresquelasminuacutesculasasiacutequeZltaesverdadyloscaracteresnoalfabeacuteticos(-yasiacuteporelestilo)sontambieacutenincluidosenelordenamientoLacomparacioacutenrealestaacutebasadaenelestaacutendarUnicodeEsteestaacutendarasignaunnuacutemeroavirtualementecadacaraacutecterquealgunaveznecesitaraacutesincluyendocaracteresdelgriegoaacuterabejaponeacutestamilyotrosalfabetosTenertalesnuacutemerosesuacutetilparaguardarlascadenasdetextodentrodelacomputadoraporquehaceposiblerepresentarlascomounasecuenciadenuacutemerosCuandocomparamoscadenasJavaScriptvadeizquierdaaderechacomparandoloscoacutedigosnumeacutericosdeloscaracteresunoporuno

Otrosoperadoressimilaressongt=(mayoroiguala)lt=(menoroiguala)==(iguala)y=(noesiguala)

consolelog(Itchy=Scratchy)rarrtrue

SoacuteloesxisteunvalorenJavaScriptquenoesigualasiacutemismoyesteesNaNquesignificanoesunnuacutemero

consolelog(NaN==NaN)rarrfalse

1ValoresTiposyOperadores

18

LaintencioacutendeNaNesrepresentarelresultadodeuncaacutelculosinsentidoycomotalnoesigualalresultadodecualquierotrocaacutelculosinsentido

OperadoresLoacutegicos

HaytambieacutenalgunasoperacionesquepuedenseraplicadasalosvaloresBooleanosJavaScriptsoportatresoperadoresloacutegicosandorynotEstospuedenserusadospararazonarconlosBooleanos

Eloperadorampamprepresentalaoperacioacutenloacutegicaand(y)Esunoperadorbinarioysuresultadoesverdadero(true)soacutelosilosdosvaloresdadossonverdaderos

consolelog(trueampampfalse)rarrfalseconsolelog(trueampamptrue)rarrtrue

Eloperador||denotalaoperacioacutenloacutegicaor(o)Devuelveverdaderosicualquieradelosdosvaloresdadosesverdadero

consolelog(false||true)rarrtrueconsolelog(false||false)rarrfalse

Not(Negacioacuten)esescritocomounsiacutembolodeadmiracioacuten()Esunoperadorbinarioquevolteaelvalorqueseledetrueproducefalseyfalseregresatrue

CuandomezclamosestosoperadoresBooleanosconaritmeacuteticayotrosoperadoresnoessiempreobviocuaacutendosenecesitanlospareacutentesisEnlapraacutecitcapuedesavanzarsabiendoquedelosoperadoresquehemosvistohastaahora||tienelamenorprecedenciadespueacutesvieneelampampsiguenlosoperadoresdecomparacioacuten(gt==etc)ydespueacuteslosdemaacutesoperadoresEsteordenhasidoelegidotalqueenexpresionestiacutepicasconlasiguienteseannecesariostanpocospareacutentesiscomoseaposible

1+1==2ampamp1010gt50

EluacuteltimooperadorloacutegicodelquehablareacutenoesunitarionibinariosinoternariooperaentresvaloresEsteesescritoconunsiacutembolodeinterrogacioacutenydospuntoscomosigue

1ValoresTiposyOperadores

19

consolelog(true12)rarr1consolelog(false12)rarr2

Esteesllamadoeloperadorcondicional(oalgunasveceseloperadortenariodadoqueeseluacutenicooperadordeestetipoenellenguaje)ElvaloralaizquierdadelsignodeinterrogacioacutenescogecuaacuteldelosotrosdosvaloresresultaraacuteCuandoesverdaderoelvalorcentralesescogidoycuandoesfalsoelvalordeladerechasedacomoresultado

ValoresIndefinidos(Undefined)

ExistendosvaloresespecialesescritosnullyundefinedquesonusadosparadenotarlaausenciadeunvalorconsignificadoSonvaloresensiacutemismosperonoposeenningunainformacioacuten

Muchasoperacionesenellenguajequenoproducenunvalorconsignificado(loveraacutesdespueacutes)producenundefinedsimplementeporquetienenqueproduciralguacutenvalor

LadiferenciaenelsignificadoentreundefinedynullesunaccidentedeldisentildeodeJavaScriptynoimportalamayoriacuteadeltiempoEnloscasosendoacutenderealmentetetienesquepreocupardeestosvaloresterecomiendotratarloscomointercambiables(maacutesdeestoenunmomento)

Conversioacutenautomaacuteticadetipos

EnlaintroduccioacutenmencioneacutequeJavaScriptaceptacasicualquierprogramaqueledesinclusoprogramasquehagancosasrarasEstoesmuybiendemostradoporlassiguientesexpresiones

consolelog(8null)rarr0consolelog(5-1)rarr4consolelog(5+1)rarr51consolelog(cinco2)rarrNaNconsolelog(false==0)rarrtrue

1ValoresTiposyOperadores

20

CuandounoperadoresaplicadoaltipoincorrectodevalorJavaScriptconvertiraacutesilenciosamenteelvaloreneltipodedatoqueesperausandounconjuntodereglasqueamenudonosonloquetuacutequieresoesperasEstoesllamadocoercioacutendetipoAsiacutequeelnullenlaprimeraexpresioacutensevuelve0yel5enlasegundaexpresioacutenseconvierteen5(decadenaanuacutemero)Auacutenasiacuteenlaterceraexpresioacuten+intentahacerconcatenacioacutendecadenasantesdesumanumeacutericaasiacutequeel1esconvertidoen1(denuacutemeroacadena)

Cuandoalgoquenosecorrespondeconunnuacutemerodemaneraobvia(comocincooundefined)esconvertidoaunnuacutemeroelvalorresultanteesNaNLassiguientesoperacionesaritmeacuteticassobreNaNseguiraacutenproduciendoNaNasiacutequesiteencuentrasconunodeestosenunlugarinesperadobuscaconversionesaccidentalesdetipo

Cuandocomparamosvaloresdelmismotipousando==lasalidaesfaacutecildepredecirdeberiacuteasobtenerverdaderocuandolosdosvaloresseanelmismoexceptoenelcasodeNaNPerocuandolostipossondiferentesJavaScriptusauncomplicadoyconfusoconjuntodereglasparadeterminarqueacutehacerEnlamayoriacuteadeloscasossoacutelotratadeconvertirunodelosvaloresaltipodedatodelotrovalorSinembargocuandonulloundefinedestaacutenencualquierladodelaoperacioacutenresultaverdaderosoacuteloenelcasodequelosdosladosseannulloundefined

consolelog(null==undefined)rarrtrueconsolelog(null==0)rarrfalse

EsteuacuteltimocomportamientoesuacutetilamenudoCuandoquieresprobarsiunvalortieneunsignificadorealenvezdenulloundefinedsimplementecomparascontranullconeloperador==(o=)

iquestYsiquieresprobarsialgoserefiereprecisamentealvalorfalseLasreglasparaconvertircadenasynuacutemerosaBooleanosdicenque0NaNylacadenavaciacutea()cuentancomofalsemientrasquetodoslosdemaacutesvalorescuentancomotrueDebidoaestoexpresionescomo0==falsey==falsetambieacutensonverdaderasParacasoscomoesteenelquenoquieresqueocurraningunaconversioacutenautomaacuteticadetiposexistendosoperadoresextra===y==ElprimeropruebasiunvaloresprecisamenteigualaotroyelsegundosinoesprecisamenteigualAsiacuteque===falseesfalsocomoseespera

YorecomiendousarlacomparacioacutendetrescaracteresdefensivamenteparaevitarqueconversionesdetiposinesperadastecausenproblemasPerocuandoestaacutessegurodequelostiposenambosladosseraacutenlosmismosnohayproblemaconusarlosoperadoresmaacutescortos

1ValoresTiposyOperadores

21

Cortocircuitodeoperadoresloacutegicos

Losoperadoresloacutegicosampampand||manejanlosvaloresdediferentestiposdeunmodopeculiarConvertiraacutenelvalordesuladoizquierdoparadecidirqueacutehacerperodependiendodeloperadorydelresultadodelaconversioacutendevuelvenelvalordelladoizquierdooriginaloeldelladoderecho

Eloperador||porejemploregresaraacuteelvalordelaizquierdacuandopuedaserconvertidoatrueyregresaraacuteelvaloraladerechaencualquierotrocasoEstaconversioacutenfuncionacomoesperariacuteasconvaloresBooleanosydeberiacuteahaceralgoanaacutelogoconvaloresdeotrostipos

consolelog(null||user)rarruserconsolelog(Karl||user)rarrKarl

Estafuncionalidadpermitealoperador||serusadocomounamaneraderespaldarnosconunvalorpordefectoSiledasenelladoizquierdounaexpresioacutenquepuedeproducirunvalorvaciacuteoelvalordeladerechaseraacuteusadocomoreemplazodadoelcaso

EloperadorampampfuncionademanerasimilarperoensentidoopuestoCuandoelvalorasuizquierdaesalgoqueseconvierteenfalsoregresaestevaloryenotrocasoregresaelvalordeladerecha

OtraimportantepropiedaddeestosdosoperadoresesqueelladoderechosoacuteloesevaluadocuandoesnecesarioEnelcasodetrue||XnoimportaloqueseaXinclusoensiesunaexpresioacutenquehacealgoterribleelresultadoseraacuteverdaderoyXnoseraacuteevaluadonuncaLomismoocurreparafalseampampXlocuaacutelesfalsoeignoraraacuteXEstoesllamadoevaluacioacutendecortocircuito(short-circuitevaluation)

EloperadorcondicionaltrabajadeunaformasimilarLaprimeraexpresioacutenesevaluadasiempreperoelsegundootercervalorelquenoseaescogidonoseevaluacutea

Resumen

VimoscuatrotiposdevaloresdeJavaScriptenestecapiacutetulonuacutemeroscadenasBooleanosyvaloresindefinidos

Estosvaloressoncreadosalescribirsunombre(truenull)ovalor(13abc)PuedescombinarytransformarvaloresconlosoperadoresVimosoperadoresbinariosparaaritmeacutetica(+-y)concatenacioacutendecadenas(+)comparacioacuten(========ltgtlt=gt=)yloacutegica(ampamp||)asiacutecomovariosoperadoresunitarios

1ValoresTiposyOperadores

22

(-parahacernegativounnuacutemeroparanegarloacutegicamenteytypeofparaobtenereltipodeunvalor)yunoperadorternario()paraelegirentredosvaloresbasaacutendonosenuntercero

EstotebrindasuficienteinformacioacutenparausarJavaScriptcomounapequentildeacalculadoraperonoparamuchomaacutesElsiguientecapiacutetuloempezaraacuteaentremezclarestasexpresionesenprogramasbaacutesicos

1ValoresTiposyOperadores

23

EstructuradelPrograma

Ymicorazoacutenbrillarojodebajodemidelgadatransluacutecidapielytienenqueadministrarme10ccdeJavaScriptparahacermeregresar(respondobienalastoxinasenlasangre)iexclHombreesacosatesacaraacutedetuscasillas_whyWhys(Poignant)GuidetoRuby

EnestecapiacutetulovamosaempezarahacercosasquerealmentepuedenserllamadasprogramacioacutenVamosaampliarnuestroconocimientodellenguajeJavaScriptmaacutesallaacutedelossustantivosyfragmentosdeoracionesquehemosvistohastaahorahastaelpuntoenquepodamosexpresaralgunaprosasignificativa

Expresionesydeclaraciones

EnelCapiacutetulo1creamosalgunosvaloresydespueacuteslesaplicamosoperadoresparaobtenernuevosvaloresCrearvaloresdeestaformaesunaparteesencialdecadaprogramadeJavaScriptperoestoessoacutelounaparte

UnfragmentodecoacutedigoqueproduceunvaloresllamadounaexpresioacutenCadavalorqueseescribeliteralmente(talcomo22opsicoanaacutelisis)esunaexpresioacutenUnaexpresioacutenentrepareacutentesisestambieacutenunaexpresioacutencomounoperadorbinarioaplicadoadosexpresionesounoperadorunarioaplicadoaunaexpresion

EstomuestrapartedelabellezadeunainterfazbasadaenellenguajeLasexpresionessepuedenanidarenunaformamuysimilaralaformadesub-frasesenlaquelaslenguashumanassonanidadasylassub-frasespuedencontenersuspropiassub-frasesetcEstonospermitecombinarexpresionesparaexpresarcaacutelculosarbitrariamentecomplejos

SiunaexpresioacutencorrespondeaunfragmentodefraseunadeclaracioacutenenJavaScriptcorrespondeaunafrasecompletaenlenguajehumanoUnprogramaessimplementeunalistadedeclaraciones

EltipomaacutessimplededeclaracioacutenesunaexpresioacutenconunpuntoycomadespueacutesdeellaEstoesunprograma

1false

EsunprogramainuacutetilsinembargoUnaexpresioacutenpuedeestarpresenteparasoacuteloproducirunvalorquepuedeentoncesserutilizadoporlaexpresioacutenquelacontieneUnadeclaracioacutenexisteporsiacutesolayqueequivaleaalgosoacutelosiafectaalmundoPodriacuteamostraralgoenlapantalla-quecuentacomocambiarelmundoopodriacuteacambiarelestadointernodela

2EstructuradelPrograma

24

maacutequinadeestadosdemaneraqueafectaraacutelasdeclaracionesquevienendespuesdeellaEstoscambiossellamanefectoscolateralesLasdeclaracionesenelejemploanteriorsoloproducenlosvalores1yverdaderoylosdesechaninmediatamenteEstonodejaninguacutencambioenelmundoenabsolutoAlejecutarelprogramanadaobservablesucede

EnalgunoscasosJavaScripttepermiteomitirelpuntoycomaalfinaldeunadeclaracioacutenEnotroscasostienequeestaralliacuteolasiguientelineaseraacutetratadacomopartedelamismadeclaracioacutenLasreglasparacuandosepuedeomitirconseguridadsonalgocomplejasypropensasaerroresEnestelibrocadadeclaracioacutenquenecesiteunpuntoycomasiempreseraacuteterminadaporunpuntoycomaTerecomiendoquehagaslomismoentuspropiosprogramasalmenoshastaquehayasaprendidomaacutessobresutilezasinvolucradasenomitirelpuntoycoma

Variables

iquestCoacutemomantieneunprogramasuestadointernoiquestCoacutemorecuerdaalgoHemosvistocoacutemoproducirnuevosvaloresdeviejosvaloresperoestonocambialosvaloresantiguosyelnuevovalortienequeserinmediatamenteutilizadoosedisiparaacutedenuevoParaatraparymantenerlosvaloresJavaScriptproporcionaunacosallamadavariable

varatrapado=55

YesonosdanuestrasegundaclasededeclaracioacutenLapalabraespecial(palabraclaveokeyword)varindicaqueestafrasevaadefinirunavariableEsseguidaporelnombredelavariableysiqueremosdardeinmediatounvalorconunoperadorde=yunaexpresioacuten

Ladeclaracioacutenanteriorcreaunavariablellamadaatrapadoyseusapararetenerelnuacutemeroqueseproducealmultiplicar5por5

DespueacutesdequeunavariablesehadefinidosunombrepuedeserusadocomounaexpresioacutenElvalordeesaexpresioacuteneselvalorquelavariablealbergaactualmenteHeaquiacuteunejemplo

vardiez=10consolelog(diezdiez)rarr100

Losnombresdevariablespuedensercualquierpalabraquenoseaunapalabraclave(talcomovar)EstosnopuedenincluirespaciosLosdiacutegitostambieacutenpuedenserpartedelavariablenombremdashcatch22esunnombrevaacutelidoporejemplo-peroelnombrenodebe

2EstructuradelPrograma

25

comenzarconundiacutegitoUnnombredevariablenopuedeincluirpuntuacioacutenaexcepcioacutendeloscaracteres$y_

CuandounavariableapuntaaunvaloresonoquieredecirqueestaacuteligadaaesevalorparasiempreEloperador=sepuedeutilizarencualquiermomentoenvariablesexistentesparadesconectarlasdesuvaloractualyapuntarlasaunonuevo

vartono=claroconsolelog(tono)rarrclarotono=oscuroconsolelog(tono)rarroscuro

PodriacuteasimaginarlasvariablescomotentaacuteculosenlugardelacajasEstasnocontienenvaloreslosagarrandosvariablespuedenreferirsealmismovalorUnprogramasoacutelopuedeaccederalosvaloresquetodaviacuteamantieneatrapadosCuandonecesitasrecordaralgohacescreceruntentaacuteculoparaagarrarloocambiasunosdetustentaacuteculosexistentesparaagarrarlo

VeamosunejemploPararecordarelnuacutemerodedoacutelaresqueLuigiauacutentedebesecreaunavariableYluegocuandotepaga$35ledasaestavariableunvalornuevo

vardeudaDeLuigi=140deudaDeLuigi=deudaDeLuigi-35consolelog(deudaDeLuigi)rarr105

2EstructuradelPrograma

26

CuandosedefineunavariablesindarleunvaloreltentaacuteculonotienenadaquesostenerporloqueterminaenelaireSipreguntasporelvalordeunavariablevaciacuteaobtendraacuteselvalorundefined(indefinido)

UnasoladeclaracioacutenvarpuededefinirmuacuteltiplesvariablesLasdefinicionesdebenestarseparadasporcomas

varuno=1dos=2consolelog(uno+dos)rarr3

Palabrasclaveypalabrasreservadas

PalabrasconunsignificadoespecialcomovarsonpalabrasclaveynopuedenserutilizadascomonombresdevariablesTambieacutenhayunnuacutemerodepalabrasquesonldquoreservadasparausordquoenfuturasversionesdeJavaScriptEstastambieacutenestaacutenoficialmentenopermitidascomonombresdevariablesaunquealgunosentornosdeJavaScriptlaspermitenLalistacompletadepalabrasclaveypalabrasreservadasesbastantelarga

breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumexportextendsfalsefinallyforfunctionifimplementsimportininstanceofinterfaceletnewnullpackageprivateprotectedpublicreturnstaticsuperswitchthisthrowtruetrytypeofvarvoidwhilewithyield

Notepreocupespormemorizarlasperorecuerdaqueestopodriacuteaserelproblemacuandounadefinicioacutendevariablenofuncionecomoseesperaba

Elentorno

LacoleccioacutendevariablesysusvaloresqueexisteenunmomentodadosellamaelentornoCuandounprogramaseponeenmarchaesteentornonoestaacutevaciacuteoSiemprecontienevariablesqueformanpartedellenguaje((estaacutendar))ylamayoriacuteadeltiempocontienevariablesqueproporcionanformasdeinteractuarconelsistemaquelocontienePorejemploenunnavegadorexistenvariablesyfuncionesparainspeccionareinfluirenlapaacuteginawebcargadaenesemomentoyleerentradadelratoacutenydelteclado

Funciones

2EstructuradelPrograma

27

UnagrancantidaddelosvaloresproporcionadosenelentornopordefectotieneneltipofunctionUnafuncioacuten(function)esunpedazodeprogramaencerradoenunvalorTalesvalorespuedenseraplicadosconelfindeejecutarelprogramaenvueltoPorejemploenunentornodenavegadorlavariablealertcontieneunafuncioacutenquemuestraunpequentildeocuadrodediaacutelogoconunmensajeSeutilizacomosigue

alert(iexclGoodMorning)

LaejecucioacutendeunafuncioacutenesdenominadainvocarllamaroaplicarlafuncioacutenPuedesllamaraunafuncioacutenponiendopareacutentesisdespueacutesdeunaexpresioacutenqueproduceunvalordelafuncioacutenPorlogeneralseusadirectamenteelnombredelavariablequecontienelafuncioacutenLosvaloresentrepareacutentesisselepasanaelprogramadentrodelafuncioacutenEnelejemplolafuncioacutenalertutilizalacadenaqueledamoscomoeltextoquesemostraraacuteenelcuadrodediaacutelogoLosvaloresdadosalasfuncionessedenominanargumentosLafuncioacutenalertnecesitasolounoperootrasfuncionespuedennecesitarunnuacutemerodiferenteodiferentestiposdeargumentos

Lafuncioacutenconsolelog

LafuncioacutenalertpuedeseruacutetilparaimprimircuandoestamosexperimentandoperoquitardelcaminotodasesaspequentildeasventanaspuededesesperarteEnejemplospasadoshemosusadoconsolelogparadevolvervaloresLamayoriacuteasistemasJavaScript(incluyendoatodoslosnavegadoreswebmodernosyaNodejs)nosdanunafuncioacutenconsolelogqueimprimesusargumentosenalguacutendispositivodesalidadetextoEnlosnavegadoreslasalidaquedaenlaconsoladeJavaScriptEstapartedelnavegadorestaacuteescondidapordefectoperolamayoriacuteadelosnavegadoreslaabrencuandopresionasF12oenMaccuandopresionasCommand-Option-ISiestonofuncionabuscaenlosmenuacutesunitemllamadoConsolaWeboHerramientasdeDesarrollador

CuandocorraslosejemplosotupropiocoacutedigoenlaspaacuteginasdeestelibrolasalidadeconsolelogseraacutemostradadespueacutesdelejemploenvezdeenlaconsoladeJavaScriptdelnavegador

varx=30consolelog(elvalordexesx)rarrelvalordexes30

2EstructuradelPrograma

28

AunquelosnombresdevariablenopuedencontenerelcaracterpuntoconsolelogclaramentetieneunoEstoesporqueconsolelognoesunavariablesimpleEsenrealidadunaexpresioacutenquetraelapropiedadlogdelvalormantenidoporlavariableconsoleVeremosquesignificaexactamenteenelCapiacutetulo4

ValoresdeRetorno

MostraruncuadrodediaacutelogooescribirtextoenlapantallaesunefectosecundarioMuchasfuncionessonuacutetilesporqueproducenvaloresyenesecasononecesitantenerunefectosecundarioparaseruacutetilesPorejemplolafuncioacutenMathmaxtomaunnuacutemeroindeterminadodenuacutemerosyregresaelmaacutesgrande

consolelog(Mathmax(24))rarr4

CuandounafuncioacutenproduceunvalorsedicequeregresaesevalorCualquiercosaqueproduceunvaloresunaexpresioacutenenJavaScriptloquesignificaquepuedeserusadadentrodeexpresionesmaacutesgrandesAquiacuteunallamadaaMathminqueesloopuestoaMathmaxesusadacomoentradadeunoperadordesuma

consolelog(Mathmin(24)+100)rarr102

Elproacuteximocapiacutetuloexplicacomoescribirtuspropiasfunciones

Pedirinformacioacutenyconfirmar

LosentornosdenavegadortienenotrasfuncionesmaacutesallaacutedealertparamostrarventanasPuedespreguntaralusuariounacuestioacutenestiloOKCancelarusandoconfirmEstoregresaunBooleanotruesielusuariohaceclickenOKyfalsesielusuariopresionaenCancelar

confirm(iquestEntoncesdeberiacuteamos)

2EstructuradelPrograma

29

LafuncioacutenpromptpuedeserusadaparahacerunapreguntaabiertaElprimerargumentoeslapreguntaelsegundoesuntextoconelqueelusuarioiniciaSepuedeescribirunaliacuteneadetextoenelcuadrodediaacutelogoylafuncioacutenregresaraacuteestetextocomounacadena

prompt(Tellmeeverythingyouknow)

Estasdosfuncionesnosonusadasmuchoenlaprogramacioacutenwebmodernaprincipalmenteporquenotienescontrolsobrelaformaenquelasventanasresultantesseveraacutenperosonuacutetilesparaprogramasdepruebayexperimentos

Controldeflujo

Cuandotuprogramacontienemaacutesdeunasentencialassentenciassonejecutadas(faacutecildepredecir)dearribahaciaabajoComounejemplobaacutesicoesteprogramatienedossentenciasLaprimeralepideunnuacutemeroalusuarioylasegundaqueseejecutadespueacutesmuestrael_cuadrado_deesenuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))alert(Tuacutenuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

LafuncioacutenNumberconvierteunvaloraunnuacutemeroNecesitamosesaconversioacutenporqueelresultadodepromptesunvalordetipocadena(string)yqueremosunnuacutemeroHayfuncionessimilaresllamadasStringyBooleanqueconviertenvaloresaestostipos

Aquiacuteestaacutelatrivialrepresentacioacutenesquemaacuteticadeunflujodecontrolrecto

EjecucioacutenCondicional

EjecutarsentenciaenliacutenearectanoeslaiacuteunicaopcioacutenquetenemosUnaalternativaeslaejecucioacutencondicionalendondneescogemosentredosrutasdiferentesbasadosenunvalorBooleanocomoelsiguiente

2EstructuradelPrograma

30

LaejecucioacutencondicionalseescribeconlapalabraclaveifenJavaScriptEnelcasosencilloqueremosquealgodecoacutedigoseejecutesiysoacutelosiciertacondicioacutensecumplePorejemploenelprogramapreviopodriacuteamosquerermostrarelcuadradodelaentradasoacutelosilaentradaesunnuacutemero

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)

Conestamodificacioacutensiledasquesonosemostraraacuteningunasalida

LapalbraclaveifejecutaosaltaunasentenciadependiendodelvalordeunaexpresioacutenBooleanaLaexpresioacutendedecisioacutenseescribedespueacutesdelapalsbraclaveentreparaacutentesisseguidaporunasentenciaaejecutar

LafuncioacutenisNaNesunafuncioacutenestaacutendardeJavaScriptqueregresatruesoacutelosielargumentoqueledisteesNaNResultaquelafuncioacutenNumberregresaNaNcuandoledasunacadenaquenoldquoamenosqueelNumeronoseaunnuacutemerordquo

AmenudonosoacutelotendraacutescoacutedigoqueseejecutecuandounacondicioacutenseaverdaderasinotambieacutenquemanejeelotrocasoEstecaminoalternativoesrepresentadoporlasegundaflechaeneldiagramaLapalabraclaveelsepuedeserusadajuntoconifparacreardosrutasdeejecucioacutenseparadasyalternativas

varelNumero=Number(prompt(Dameunnuacutemero))if(isNaN(elNumero))alert(Tunuacutemeroeslaraiacutezcuadradade+elNumeroelNumero)elsealert(HeyiquestPorqueacutenomedisteunnuacutemero)

SitenemosmaacutesdedoscaminosaescogervariosparesdeifelsepuedenserencadenadosAquiacutehayunejemplo

2EstructuradelPrograma

31

varnum=Number(prompt(Dameunnuacutemero0))

if(numlt10)alert(Chico)elseif(numlt100)alert(Mediano)elsealert(Grande)

Elprogramaprimerochecaraacutesiacutenumesmenorque10SiloesescogeesecaminomuestraChicoyterminaSinoloestomaelcaminoelsequeensiacutemismocontieneunsegundoifSilasegundacondicioacuten(lt100)secumplesignificaqueelnuacutemeroestaacuteentre10y100ysemuestraMedianoSinoloeselsegundoyuacuteltimoelseesescogido

Eldiagramadeflujoparaesteprogramaesalgoasiacute

bucleswhileydo

Piensaenunprogramaqueimprimatodoslosnuacutemerosprimosdel1al12Unamaneradeescribirloseriacuteacomosigue

consolelog(0)consolelog(2)consolelog(4)consolelog(6)consolelog(8)consolelog(10)consolelog(12)

EsofuncionaperolaideadeescribirunprogramaestrabajarmenosnomaacutesSinecesitamostodoslosnuacutemerosmenoresque1000loanteriorseriacuteaimposibledetrabajarLoquenecesitamosesunaformaderepetiralgodecoacutedigoEstaformadecontroldeflujoesllamadabucle

2EstructuradelPrograma

32

ElcontroldeflujodelbuclenospermiteiratraacutesaalguacutenpuntoenelprogramadondeestaacutebamosantesyrepetirloconnuestroactualestadodelprogramaSicombinamosestoconunavariablecontadorapodemoshaceralgoasiacute

varnumber=0while(numberlt=12)consolelog(number)number=number+2rarr0rarr2hellipetcetera

UnasentenciaquecomienzaconlapalabraclavewhilecreaunbucleDespueacutesdelapalabrawhilevieneunaexpresioacutenenpareacutentesisydespueacutesunasentenciamuyparecidoaelifElbucleejecutalasentenciamientraslaexpresioacutenproduzcaunvalorqueseatruecuandoseconvierteauntipoBooleano

EnestebuclequeremostantoimprimirelnuacutemerocomosumardosanuestravariableCuandonecesitamosejecutarmuacuteltiplessentenciasdentrodeunbucleloencerramosenllaves(y)LasllaveshacenporlassentenciasloquelospareacutentesishacenporlasexpresioneslasagrupanhacieacutendolosvalerporunasolasentenciaUnasecuenciadesentenciasencerradasenllavesesllamadaunbloque

MuchosprogramadoresdeJavaScriptencierrancadacuerpodeunbucleifenllavesLohacenennombredelaconsistenciayparaevitartenerqueantildeadiroquitarlasllavescuandoelnuacutemerodesentenciasenelcuerpocambieEnestelibroescribireacutelamayoriacuteadeloscuerposdeunasolasentenciasinbloquesporquevaluacuteolabrevedadTuacuteereslibredeusarelestiloqueprefieras

LavariablenuacutemerodemuestralaformaenqueunavariablepuededarseguimientoalprogresodeunprogramaCadavezqueelbucleserepitenumeroseincrementaen2Entoncesalprincipiodecadarepeticioacutenescomparadaconelnuacutemero12paradecidirsielprogramahahechotodoeltrabajoqueteniacuteaquehacer

Comounejemploquehacerealmentealgouacutetilpodemosescribirunprogramaquecalculaymustraelvalorde2^10(dosaladeacutecimapotencia)UsamosdosvarianlesunaparamantenerelresultadoyunaparacontarcuantasveceshemosmultiplicadoesteresultadopordosElbucleverificasilasegundavariablehallegadoa10yentoncesactualizalasdosvariables

2EstructuradelPrograma

33

varresult=1varcounter=0while(counterlt10)result=result2counter=counter+1consolelog(result)rarr1024

Elcontadorpudotambieacutenempezaren1yverificarqueelcontadorsealt=10peroporrazonesqueseaclararaacutenenelCapiacutetulo4esunabuenaideaacostumbrarseacontardesde0

ElbucledoesunaestructuradecontrolsimilaralbuclewhileSediferenciaensoacutelounpuntounbucledosiempreejecutasucuerpoporlomenosunavezyempiezaaverificarsideberiacuteapararsoacutelodespueacutesdelaprimeraejecucioacutenParareflejarestolacondicioacutenaparecedespueacutesdelcuerpodelbucle

dovaryourName=prompt(Whoareyou)while(yourName)consolelog(yourName)

EsteprogramateobligaraacuteaintroducirunnombrePreguntaraacuteunayotravezhastaqueobtengaalgoquenoseaunacadenavaciacuteaAplicareloperadorconvierteunvaloraBooleanonegaacutendoloytodaslascadenasexceptoseconviertenatrueEstosignificaqueelbuclecontinuacuteacorriendohastaquedesunnombrequenoseaunacadenavaciacutea

Indentandocoacutedigo

ProbablementehasnotadolosespaciosquepongoenfrentedealgunassentenciasEnJavaScriptnosonrequeridoslacomputadoraaceptaraelprogramabiensinellosDehechoinclusolossaltosdeliacuteneaenlosprogramassonopcionalesPuedesescribirunprogramaenunasolaliacuteneasiasiacuteloprefieresElroldelaindentacioacutendentrodelosbloqueseshacernotarlaestructuradelcoacutedigoEncoacutedigocomplejoendoacutendenuevosbloquessonabiertosdentrodeotrosbloquespuedeserdifiacutecildeverendoacutendeterminaunoyempiezaotroConlaindentacioacutencorrectalaformavisualdelprogramasecorrespondeconlaformadelosbloquesdentrodeeacutelAmiacutemegustausardosespaciosporcadabloqueabiertoperolosgustosvariacuteanalgunaspersonasusancuatroespaciosyalgunasotrasusanelcaraacutectertab

Buclesfor

2EstructuradelPrograma

34

MuchosbuclessiguenelpatroacutendelosejemplospreviosdelwhilePrimerounavariableldquocontadorrdquoescreadaparadarseguimientoalprogresodelbucleEntoncesvieneunbuclewhilecuyaexpresioacutencondicionalnormamelteverificasielcontadorhaalcanzafociertoliacutemiteEnelfinaldelcuerpodelbucleelcontadoresactualizadoparadarseguimientoalprogreso

DebidoaqueestepatroacutenestancomuacutenJavaScriptyloslenguajessimilaresproveenunaformaunpocomaacutescortayfacildeentenderelbuclefor

for(varnumber=0numberlt=12number=number+2)consolelog(number)rarr0rarr2hellipetcetera

EsteprogramaequivaleexactamentealejemploanteriorEluacutenicocambioesquetodaslasdeclaracionesqueserefierenalestadodelbucleestaacutenahoraagrupadasentreellas

LospareacutentesisposterioresaunapalabraclavefordebencontenerdospuntoycomaLaprimeraparteantesdelprimerpuntoycomainicializaelbucleporlogeneraldefiniendolavariableLasegundaparteeslaexpresioacutenquecompruebasielbucledebecontinuarLapartefinalactualizaelestadodelbucledespueacutesdecadarepeticioacutenLamayoriacuteadelasvecesestoesmaacutescortoyclaroqueunaconstruccioacutenwhile

Aquiacuteelcoacutedigoquecomputa2^10usandoforenlugardewhile

varresult=1for(varcounter=0counterlt10counter=counter+1)result=result2consolelog(result)rarr1024

Notaqueaunqueninguacutenbloqueestaacuteabiertoconladeclaracioacutenenelbucleestaacuteauacutensangradacondosespaciosparahacerclaroquepertenecealaliacuteneaanterior

Deteniendounbucle

HacerquelacondicionpruduzcafalseenelbuclenoeslauacutenicaformaenqueunbuclepuedeterminarHayunadeclaracioacutenespecialllamadobreakquetieneelefectodesaltarinmediatamentefueradelbuclecerrado

EsteprogramailustralasentenciabreakEncuentraelprimernuacutemeroqueesmayoroiguala20ydivisibleentre7

2EstructuradelPrograma

35

for(varcurrent=20current++)if(current7==0)breakconsolelog(current)rarr21

Usandoeloperador()esunaformafaacutecildecomprobarsiunnuacutemeroesdivisibleentreotronuacutemeroSiesasiacuteelrestodesudivisioacutenescero

ElconstructorforenelejemplonotieneunapartequereviseelfindelbucleEstosignificaqueelbuclenuncasedetendraacuteamenosqueladeclaracioacutenbreakseejecutedesdeadentro

SitudejarasfueraladeclaracioacutenbreakoescribierasaccidentalmenteunacondicioacutenquesiempreproduceverdaderotuprogramaquedaraacuteatoradoenunbucleinfinitoUnprogramaatoradoenunbucleinfinitonuncaterminaraacutedecorrerloquenormalmenteesalgomalo

SicreasunbucleinfinitoenunodelosejemplosdeestaspaacuteginasnormalmenteelnavegadortepreguntarasiquieresdetenerlasecuenciadecomandosdespueacutesdeunoscuantossegundosSiesofallatendraacutesquecerrarlapestantildeaenlaqueestaacutestrabajandooenalgunosnavegadorescerrarlocompletamenteconelfinderecuperarlo

LapalabraclavecontinueessimilarabreakenestainfluyeenelprogresodeunbucleCuandocontinueseencuentradentrodelcuerpodelbucleelcontrolsaltafueradelcuerpoycontinuacuteaconlasiguienterepeticioacutendelbucle

Actualizarvariablesenbreve

Particularmentecuandosehaceunbucleunprogramaamenudonecesitaactualizarunavariableparamantenerunvalorbasadoenelvalorpreviodeesavariable

counter=counter+1

JavaScriptproveeunatajoaesto

counter+=1

Atajossimilarestrabajanparamuchosotrosoperadorescomoresultado=2paradoblarelresultadoocontador-=1paracontardescendente

Estonospermiteacortarunpocomaacutesnuestroejemplodeconteo

2EstructuradelPrograma

36

for(varnumber=0numberlt=12number+=2)consolelog(number)

Paracontador+=1ycontador-=1existeninclusoequivalentesmaacutescortoscontador++ycontador--

Enviandoenunvalorconswitch

Escomuacutenqueelcodigoseveaasiacute

if(variable==value1)action1()elseif(variable==value2)action2()elseif(variable==value3)action3()elsedefaultAction()

HayunconstructorllamadoswitchqueestaacutepensadoparafuncionarcomoundespachadorenunamaneramaacutesdirectaDesafortunadamentelasintaxisqueJavaScriptusaparaesto(locualheredadelenguajesdeprogramacioacutencomoCJava)queesdealgunamaneramenoseficientequeunacadenadedeclaracionesifqueamenudosevemejorAquiacuteunejemplo

switch(prompt(Whatistheweatherlike))caserainyconsolelog(Remembertobringanumbrella)breakcasesunnyconsolelog(Dresslightly)casecloudyconsolelog(Gooutside)breakdefaultconsolelog(Unknownweathertype)break

PodraacutesponercualquiernuacutemerodeetiquetascasedentrodelbloqueabiertoporswitchElprogramasaltaraacutealaetiquetaquecorrespondealvalorqueswitchdioacuteoeldefaultsinocoincideelvalorEstoempiezaaejecutardeclaracionesalliacuteaunqueesteacutenbajootra

etiquetahastaquealcancenunadeclaracioacutenbreakEnalgunoscasoscomoeldelcasosunnyenelejemploestopuedeserusadoparacompartiralgodecoacutedigoentrecasos(estorecomiendairfueraporambosclimassoleadoynuboso)Perotencuidadoesfaacutecil

olvidarunbreak`locualcausaraacutequeelprogramaejecutecoacutedigoquenoquieresqueseejecute

2EstructuradelPrograma

37

Mayuacutesculas

LosnombresdevariablesnodebecontenerespaciossinembargoescomuacutenayudarseusandomuacuteltiplespalabrasqueclaramentedescribanloquelavariablerepresentaEstassoncasitusuacutenicaopcionesparaescribirunnombredevariableconvariaspalabrasenella

fuzzylittleturtlefuzzy_little_turtleFuzzyLittleTurtlefuzzyLittleTurtle

ElprimerestilopuedeserdifiacutecildeleerPersonalmenteMegustacomosevenlosguionesbajossinembargoeseestiloesunpococomplicadodeescribirLasfuncionescomunesJavaScriptylamayoriacuteadeprogramadoresJavaScriptsigueneluacuteltimoestilo-ellosponenenmayuacutesculascadapalabraexceptolaprimeraNoesdifiacutecilacostumbraseacosaspequentildeascomoestayescribircoacutedigoconestilosdenombresmixtospuedesertediosodeleerasiacutequenosotrossoacuteloseguiremosesteconvencioacuten

EnalgunoscasoscomoenlafuncioacutenNumberlaprimeraletradeunavariableestambieacutenmayuacutesculaEstosehizoparasentildealarestafuncioacutencomounconstructorLoqueesunconstructorvendraacuteclaramenteenelcapiacutetulo6Porahoraloimportanteesnoestarpreocupadoporestaaparentefaltadeconsistencia

Comentarios

AmenudoelcoacutedigocrudonotransmitetodalainformacioacutenquequieresqueunprogramatransmitaaloslectoreshumanosotransmiteenunaformacomoencriptadaquelagentenopuedeentenderEnotrosmomentostepuedessentirpoeacuteticooqueriendoincluiralgunospensamientoscomopartedetuprogramaEstoesparaloquesonloscomentarios

UncomentarioesunpedazodetextoqueespartedeunprogramaperoescompletamenteignoradoporlacomputadoraJavaScripttienedosmanerasdeescribircomentariosParaescribiruncomentariodeunasolaliacuteneapuedesusardosdiagonales()yeltextodelcomentariodespueacutes

varaccountBalance=calculateBalance(account)ItsagreenhollowwhereariversingsaccountBalanceadjust()Madlycatchingwhitetattersinthegrassvarreport=newReport()WherethesunontheproudmountainringsaddToReport(accountBalancereport)Itsalittlevalleyfoaminglikelightinaglass

2EstructuradelPrograma

38

UncomentariovauacutenicamentealfinaldelaliacuteneaUnaseccioacutendetextoentreyseraacuteignoradasintenerencuentaloquecontengaEstoesamenudouacutetilparaagregarbloquesdeinformacioacutenacercadeunarchivoountrozodeprograma

IfirstfoundthisnumberscrawledonthebackofoneofmynotebooksafewyearsagoSincethenithasoftendroppedbyshowingupinphonenumbersandtheserialnumbersofproductsthatIveboughtItobviouslylikesmesoIvedecidedtokeepitvarmyNumber=11213

Resumen

AhoratusabesqueunprogramaestaacuteconstruidopordeclaracioneslascualesporsimismascontienenmaacutesdeclaracionesLasdeclaracionestiendenacontenerexpresioneslascualesensimismaspuedenserconstruidasdesdeexpresionesmaacutespequentildeas

PonerdeclaracionesdespueacutesdeotratedaunprogramaqueesejecutadodearribaaabajoPuedesingresarinterrupcionesenelcontroldeflujoutilizandodeclaracionescondicionales(ifelseyswitch)ydebucle(whiledoyfor)

LasvariablespuedenserusadasparaarchivarpedazosdedatosdentrodeunnombreysonuacutetilespararastrearestadosentuprogramaElambienteeselconjuntodevariablesquesondefinidasLossistemasJavaScriptsiempreponenunnuacutemerodevariablesestaacutendaruacutetilesatuambiente

LasfuncionessonvaloresespecialesqueencapsulanunpedazodeprogramaPuedesinvocarlasescribiendonombreDeFuncion(argumento1argumento2)Asiacutecomounallamadaafuncioacutenesunaexpresioacutenypuedeproducirunvalor

Ejercicios

Sinoestaacutessegurodecomoprobartussolucionesalosejerciciosdirigetealaintroduccioacuten

CadaejerciciocomienzaconunadescripcioacutendeunproblemaLeacuteeloytrataderesolverelejercicioSiteencuentrasenproblemasconsideraleerlosconsejosdespueacutesdelejercicioLassolucionescompletasalosejerciciosnoestaacutenincluidasenestelibroperopuedesencontrarlasenliacuteneaenhttpeloquentjavascriptnetcodeSiquieresaprenderalgodelosejerciciosrecomiendobuscarlassolucionesuacutenicamentedespueacutesderesolverelejerciciooalmenosdespueacutesdequehayastratadolomaacutesduroposibleyquetengasunligerodolordecabeza

2EstructuradelPrograma

39

Buclearuntriangulo

Escribeunbuclequehagasietellamadasaconsolelogparamostrarelsiguientetriangulo

Puedeseruacutetilsaberquepuedesencontrarellargodelacadenadetextoescribiendolenghtdespueacutesdeesta

varabc=abcconsolelog(abclength)rarr3

LamayoriacuteadelosejercicioscontienenunpedazodecoacutedigoquepuedesmodificarpararesolverelejercicioRecuerdaquepuedesclickearbloquesdecoacutedigoparaeditarlos

Yourcodehere

Consejo

Puedescomenzarconunprogramaquesimplementeimprimalasalidadenuacutemeros1al7loscualespuedesderivarhaciendounapocasmodificacionesalejemplodeimpresioacutendenuacutemeropardadoantesenestecapiacutetulodondeelbucleforfuepresentado

AhoraconsideralaequivalenciaentrenuacutemerosycadenasdetextodecaracteresdenuacutemeroPuedesirde1a2agregando1(+=1)Puedesirdeaagregandoelcaracter(+=)Porlotantotusolucioacutenpuedeestarcercadelprogramanumber-printing

FizzBuzz

Escribeunprogramaqueuseconsolelogparaimprimirtodoslosnuacutemerosdel1al100condosexcepcionesParanuacutemerosdivisiblespor3imprimeFizzenlugardelnuacutemeroyparanuacutemerosdivisiblesen5(yno3)imprimeBuzzensulugar

2EstructuradelPrograma

40

CuandotengastrabajandoesomodificatuprogramaparaimprimirFizzBuzzparanuacutemerosquesondivisiblesporambos3y5(yqueauacutenimprimaFizzoBuzzparanuacutemerosdivisiblesporuacutenicamenteunodeesos)

(EstoesenrealidadunapreguntadeentrevistaquehasidoelaboradaparaquitarunsignificanteporcentajedecandidatosaprogramadorEntoncessiloresuelvespuedessentirtebiencontigomismo)

Yourcodehere

Consejo

IrsobrelosnuacutemerosesclaramenteuntrabajodebucleyseleccionarqueseimprimeesunacuestioacutendeejecucioacutencondicionalRecuerdaeltrucodeusarunoperadorderesultado()pararevisarsiunnuacutemeroesdivisibleporotronuacutemero(tieneunresultadocero)

Enlaprimeraversioacutenexistentresposiblesresultadosparacadanuacutemeroentoncestienesquecrearunacadenadeifelseifelse

LasegundaversioacutendelprogramatieneunsolucioacutendirectaeinteligenteLamanerasimpleesagregarotraramaparaprecisamenteprobarlacondicioacutendadaParaelmeacutetodointeligenteconstruyeunacadenadetextoconteniendolapalabraopalabrasasalireimprimeyaseaestapalabraoelnuacutemerosiesquenohayunapalabrapotencialmentehaciendousodeloperadorelegante||

Tablerodeajedreacutez

Escribeunprogramaquecreeunacadenadetextoquerepresenteunarejillade8x8usandocaracteresnewlineparasepararliacuteneasAcadaposicioacutendelarejillayaseaunespacioouncaracterLoscaracteresdeberiacuteanformaruntablerodeajedrez

Pasandoestacadenadetextoaconsolelogdeberiacuteamostraralgocomoesto

2EstructuradelPrograma

41

Cuandotienesunprogramaquegeneraestepatroacutendefineunavariablesize=8ycambiaelprogramademodoqueestetrabajeparacualquiertamantildeoimprimiendounarejilladeanchoyaltodado

Yourcodehere

Consejo

Lacadenadetextopuedeserconstruidacomenzandoconun()vaciacuteoyrepetidamenteagregandocaracteresUncaracternewlineesescriton

Usaconsolelogparainspeccionarlasalidadetuprograma

ParatrabajarcondosdimensionesnecesitaraacutesunbucledentrodeunbuclePonllavesalrededordeloscuerposdeambosbuclesparahacerfaacutecildeverdondeempiezanyterminanTratacorrectamentedeidentificarloscuerposElordendelosbuclesdebenseguirelordenencualconstruiremoslacadenadetexto(liacuteneaaliacuteneaizquierdaaderechaarribaaabajo)Entoncesparaqueelbucleexteriormanejelasliacuteneasyelbucleinteriormanejeloscaracteresenunaliacutenea

NecesitasdosvariablespararastreartuprogresoParasabersiponerunespacioounsignodenuacutemeroaunadeterminadaposicioacutenpuedesprobarsilasumadelosdoscontadoresespar(2)

Poniendofinaunaliacuteneaagregandouncaracternewlinesucededespueacutesquelaliacuteneahasidoconstruidaporlotantohazestodespueacutesdelbucleperodentrodelotrobucle

2EstructuradelPrograma

42

FuncionesLagentepiensaquelascienciasdelacomputacioacutensonelartedelosgeniosperolarealidadeslocontrarioessoacutelounmontoacutendegentehaciendocosasqueseconstruyensobreotrascomounapareddepiedrasmuypequentildeasDonaldKnuth

HasvistovaloresfuncioacutencomoalertycoacutemollamarlosLasfuncionessonelpandecadadiacuteaenlaprogramacioacutenenJavaScriptElconceptodedeenvolverunaporcioacutendelprogramaenunvalor(variable)tienemuchosusosEsunaherramientaparaestructurarprogramasmaacutesgrandesparareducirlarepeticioacutenparaasociarnombresconsubprogramasyparasepararestosprogramasdelosdemaacutes

LaaplicacioacutenmaacutesobviadelasfuncionesesladedefinirunnuevovocabularioCrearnuevaspalabrasenlaprosaregularenlenguajehumanoesusualmenteunmalestiloPeroenprogramacioacutenesindispensable

Unadultopromediotieneunas20000palabrasensuvocabularioPocoslenguajesdeprogramacioacutentienen20000comandosincorporadosYelvocabularioqueestaacutedisponibletiendeaserdefinidodeformamaacutesprecisaasiacutequeesmenosflexiblequeenunlenguajehumanoEnconsecuenciausualmentetenemosqueantildeadiralgodenuestropropiovocabularioparaevitarrepetirnosdemasiado

Definiendounafuncioacuten

UnadefinicioacutendeunafuncioacutenessoacutelounadefinicioacutenregulardeunavariablecuandoocurrequeelvalordadoalavariableesunafuncioacutenPorejemploelsiguientecoacutedigodefinelavariablecuadradoparareferirsealafuncioacutenqueproduceelcuadradodeunnuacutemerodado

varcuadrado=function(x)returnxx

consolelog(cuadrado(12))rarr144

UnafuncioacutenescreadaporunaexpresioacutenqueempiezaconlapalabrareservadafunctionLasfuncionestienenunconjuntodeparametros(enestecasosoacutelox)yuncuerpoquecontienelassentenciasqueseraacutenejecutadascuandolafuncioacutenseallamadaElcuerpodelafuncioacutentienequeestarsiempreencerradoenllavesinclusocuandoconsistadeunasolainstruccioacuten(comoenelejemploprevio)

3Funciones

43

UnafuncioacutenpuedetenervariosparaacutemetrosopuedenotenerningunoEnelsiguienteejemplohazRuidonotieneparaacutemetrosmientrasquepotenciatienedos

varhazRuido=function()consolelog(Pling)

hazRuido()rarrPling

varpotencia=function(baseexponente)varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(210))rarr1024

AlgunasfuncionesproducenunvalorcomopotenciaycuadradoyalgunasnocomohazRuidolacuaacutelproducesoacutelounefectosecundarioUnasentenciareturndeterminaelvalorqueunafuncioacutenregresaCuandoelcontrolpasaaestasentenciainmediatamentesaltafueradelafuncioacutenactualypasaelvalorretornadoalacoacutedigoquellamoacutelafuncioacutenLapalabrareservadareturnsinunaexpresioacutendespueacutesdeellaharaacutequelafuncioacutendevuelvaundefined

Paraacutemetrosyaacutembitos

Losparametrosparaunafuncioacutensecomportancomovariablesnormalesperosuvalorinicialestadadoporquienllamaalafuncioacutennoporelcoacutedigomismodelafuncioacuten

UnpropiedadimportantedelasfuncionesesquelasvaribalescreadesdentrodeellasincluyendosusparaacutemetrossonlocalesparalafuncioacutenEstosignificaporejemploquelavaribaleresultadoenelejemplopotenciaseraacutecreadadenuvocadavezquelafuncioacutenesllamadayestasinstanciasseparadasnointerfierenentreellas

EstalocalidaddelasvariablesaplicasoacuteloalosparaacutemetrosyvariablesdeclaradasconlapalabrareservadavardentrodelcuerpodelafuncioacutenLasvariablesdeclaradasfueradecualquierfuncioacutensonllamadasglobalesporquesonvisiblesatraveacutesdetodoelprogramaEsposibleaccederaestasvariablesdesdedentrodeunafuncioacutenmientrasnohayasdeclaradounavariablelocalconelmismonombre

3Funciones

44

ElsiguientecoacutedigodemuestraesoDefineyllamadosfuncionesqueasignanunvaloralavariablexLaprimeradeclaralavariablecomolocalydeestamaneracambiauacutenicamentelavariablequecreoacuteLasegundanodeclaraxlocalmenteasiacutequelaxdentrodeellahacereferenciaalaxdefinidaalprincipiodelejemplo

varx=fuera

varf1=function()varx=dentrodef1f1()consolelog(x)rarrfuera

varf2=function()x=dentrodef2f2()consolelog(x)rarrdentrodef2

EstecomportamientoayudaaprevenirinterferenciaaccidentalentrelasfuncionesSitodaslasvariablesfuerancompartidasporelprogramaenteroseriacuteamuydifiacutecilasegurarsedequealguacutennombrenofueusadoparadospropoacutesitosdiferentesYsireusasteunnombredevariablepodriacuteasverefectosextrantildeosdecoacutedigonorelacionadocausandoproblemasenelvalordetuvariablelafuncionaltratartusvariableslocalesellenguajehaceposibleleeryentenderlasfuncionescomounpequentildeosuniversossintenerquepreocuparsedetodoelcoacutedigoalavez

AacutembitosAnidados

JavaScriptdistinguenossoloentrevariablesglobalesylocalesLasfuncionespuedensercreadasdentrodeotrasfuncionesproduciendodistindosgradosdelocalidad

Porejemploestafuncioacutensinsentidotienedosfuncionesdentrodeella

3Funciones

45

varpaisaje=function()varresultado=varmeseta=function(tamano)for(varcuenta=0cuentaltsizecuenta++)resultado+=_varmontana=function(tamano)result+=for(varcuenta=0cuentaltsizecuenta++)resultado+=resultado+=

meseta(3)montana(4)meseta(6)montana(1)meseta(1)returnresultado

consolelog(landscape())rarr__________

LasfuncionesmesetaymontanapuedenverlavariablellamadaresultadodebidoaqueestaacutendentrodelafuncioacutenqueladefinePeronopuedenverlavariablecuentaentreellasporqueestaacutendefinidasfueradelaacutembitodelaotraElentornofueradelafuncioacutenpaisajenopuedeaccederaningunadelasvariablesdefinidasdentrodepaisaje

EnpocaspalabrascadaaacutembitolocaltambieacutenpuedeverlosaacutembitoslocalesquelocontienenElconjuntodevariablesvisibledentrodelafuncioacutenesdeterminadoporellugardelafuncioacuteneneltextodelprogramaTodaslasvariablesdelosbloquesqueenvuelvenunaladefinicioacutendeunafuncioacutensonvisiblesparaellaestoesentodosloscuerposdelasfuncionesquelaenvuelvenylascorrespondientesalnivelsuperior(aacutembitoglobal)Estemaneraderesolverlavisibilidaddelasvariablesesllamadadefinicioacutenleacutexicadeaacutembito(lexicalscoping)

LaspersonasquetienenexperienciaconotroslenguajesdeprogramcioacutenpodriacuteanesperarquecualquierbloqueentrellavesproduzcaunnuevoentornolocalPeroenJavaScriptlasfuncionessonlouacutenicoquecreaunnuevoaacutembitoPeropuedesusarbloquesindependientes

3Funciones

46

varalgo=1varalgo=2HazalgoconlavariableFueradelbloque

PerolavariablealgodentrodelbloqueserefierealamismavariablequelaqueestaacutefueradelbloqueDehechoaunquebloquescomoestesonpermitidossoacutelosonuacutetilesparaagruparelcuerpodelassentenciasifodelosbucles

SiestotepareceraronoereseluacutenicoLaproacuteximaversioacutendeJavaScriptintroduciraacuteunapalabrareservadaletquetrabajacomovarperocreaunavariablequeeslocalparaelbloqueenelqueestaacutenoparalafuncioacuten

Funcionescomovalores

LasvariablesdefuncioacutennormalmenteactuacuteancomonombresparaunaparteespeciacuteficadelprogramaEsavariablesesdefinidaunavezynuncaescambiadaEstohacefaacutecilempezaraconfundirlafuncioacutenconsunombre

PerosondiferentesentresiacuteUnvalorfuncioacutenpuedehacertodolosquelosotrosvalorespuedenhacerlopuedesusarenexpresionesarbitrariasnosoacutelollamarlosEsposibleguardarlafuncioacutenenunnuevolugarpasarcomoargumentoaotrafuncioacutenetcDemaneraparecidalavariablequecontieneunafuncioacutensiguesiendounavariablenormalalaqueselepuedeasignarotrovalorcomosigue

varlanzarMisiles=function(valor)sistemaDeMisileslanzar(ahora)if(modoSeguro)lanzarMisiles=function(valor)Nohacernada

EnCapiacutetulo5hablaremosdelasmaravillosascosasquepuedeshaceralpasarvaloresfuncioacutenaotrasfunciones

NotacioacutendeDeclaracioacuten

Existeunaformamaacutescortadedecirldquovarsquare=functionhelliprdquoLapalabrareservadafunctionpuedeserusadaalprincipiodeunasentenciacomosigue

3Funciones

47

functioncuadrado(x)returnxx

EstaesunadeclaracioacutendefuncioacutenLaexpresioacutendefinelavariablecuadradoylaapuntaalafuncioacutendadaHastaaquiacutetodobiensinembargohayunapequentildeasutilezaconestaformadedefinicioacuten

consolelog(Elfuturodicefuturo())

functionfuture()returnSeguimossintenercarrosvoladores

EstecoacutedigofuncionaaunquelafuncioacutenestaacutedefinidadebajodelcoacutedigoquelausaEstoesdebidoaquelasdeclaracionesdefuncioacutennotomanparteenelflujodecontrolregulardearribahaciaabajoSonmovidasconceptualmentealapartesuperiordesuaacutembitoypuedenserusadasportodoelcoacutedigoeneseaacutembitoEstoesuacutetilalgunasvecesporquenosdalalibertaddeorganizarelcoacutedigodeunamaneraparezcasignificativasinpreocuparnospordefinirtodaslasfuncionesantesdesuprimeruso

iquestQueacutepasacuandoponesunadeclaracioacutendefuncioacutendentrodeunbloquecondicional(if)odentrodeunbucleBuenomejornolohagasDiferentesplataformasdeJavaScriptendiferentesnavegadoreshacendiferentescosastradicionalmenteenesasituacioacutenyeluacuteltimoestaacutendardehecholoprohibeSiquieresquetusprogramasseanconsistentesusalassentenciasdedeclaracioacutendefuncioacutenenelbloquemaacutesexternodetufuncioacutenoprograma

functionejemplo()functiona()Bienif(alguna_condicion)functionb()iexclPeligro

Lapiladellamadas

SeraacuteuacutetilmirarmaacutesdecercalaformaenqueelcontrolsemueveatraveacutesdelasfuncionesAquiacutehayunsimpleprogramaquehaceunascuantasllamadasafunciones

3Funciones

48

functionsaluda(a_quien)consolelog(Hola+a_quien)saluda(Harry)consolelog(Adioacutes)

Unaejecucioacutendeesteprogramavamaacutesomenosasiacutelallamadaasaludacausaqueelcontrolpasealiniciodeesafuncioacuten(liacutenea2)Estallamaacontrollog(unafuncioacutenincluiacutedaenlosnavegadores)quetomaelcontrolhacesutrabajoydevuelveelcontrolalaliacutenea2Despueacutessealcanzaelfinaldelafuncioacutensaludaasiacutequeseregresaallugarendoacutendesellamoacuteenlaliacutenea4Laliacuteneasiguientellamaaconsolelogotravez

Podemosmostrarelflujodecontrolesquemaacuteticamenteasiacute

raiacutezsaludaconsolelogsaludaraiacutezconsolelograiacutez

DebidoaqueunafuncioacutentienequesaltarderegresoallugarenquefuellamadacuandoterminelacomputadoradeberecordarelcontextoenelquefuellamadaEnuncasoconsolelogtienequeregresaralafuncioacutensaludaEnelotrocasosaltaalfinaldelprograma

EllugarenelquelacomputadoraguardaestecontextoeslapiladellamadasCadavezqueunafuncioacutenesllamadaelcontextoactualespuestoenlapartesuperiordeestapilaCuandolafuncioacutenretorneremueveelcontextosuperiordelapilaylousaparacontinuarlaejecucioacuten

GuardarestapilarequiereespacioenlamemoriadelacoputadoraCuandolapilasehacedemasiadograndelacomputadoramostraraacuteunerrorparecidoaoutofstackspace(sinespacioenlaenlapila)otoomuchrecursion(demasiadarecursioacuten)ElsiguientecoacutedigoloilustraalpreguntarlealgorealmentedifiacutecilalacomputadoraloquecausauniryvenirinfinitamenteentrefuncionesMaacutesbienseriacuteainfinitosilacomputadoratuvieraunapilainfinitaComosonlascosasnosquedaremossinespacioovolaremoslapila

3Funciones

49

functiongallina()returnhuevo()functionhuevo()returngallina()consolelog(gallina()+fueprimero)rarr

ArgumentosOpcionales

Elsiguientecoacutedigoespermitidoyseejecutasinninguacutenproblema

alert(HolaBuenasNochesiquestCoacutemoestaacutes)

LafuncioacutenalertoficialmenteaceptasoacutelounargumentoAuacutenasiacutecuandolallamascomoaquiacutenosequejaSimplementeignoralosotrosargumentosytemuestraHola

JavaScriptesdementeextremadamenteabiertasobreelnuacutemerodeargumentosquelepasasaunafuncioacutenSiacutelepasasdemasiadoslosargumentosextrasonignoradosSilepasasmuypocoslosparaacutemetrosquefaltansimplementesonasignadosaundefined

Elladomalodeestoesqueesposbibleprobablecasiseguroquelepasaraacutesaccidentalmenteunnuacutemeroincorrectodeargumentosalasfuncionesynadieteavisaraacute

ElladobuenodeestecomportamientoesquepuedeserusadoparatenerunafuncioacutenquetomeparaacutemetrosopcionalesPorejemplolasiguienteversioacutendepotenciapuedeserllamadacondosargumentosounosolocasoenelqueelexponenteseasumecomodosylafuncioacutensecomportacomocuadrado

functionpotencia(baseexponente)if(exponente==undefined)exponente=2varresultado=1for(varcuenta=0cuentaltexponentecuenta++)resultado=basereturnresultado

consolelog(potencia(4))rarr16consolelog(potencia(43))rarr64

3Funciones

50

EnelproacuteximocapiacutetuloveremosunaformaenlaqueelcuerpodeunafuncioacutenpuedeobtenerlalistaexactadeargumentosqueselepasaronEstoesuacutetilporquepermiteaunafuncioacutenaceptarunnuacutemeroindeterminadodeargumentosPorejemploconsoleloghaceusodeestoimprimetodoslosvaloresqueselepasaron

consolelog(R2D2)rarrR2D2

Closure

Lahabilidaddetratarfuncionescomovalorescombinadaconelhechodequelasvaribleslocalessonre-creadascadavezqueunafuncioacutenesllamadasacaalaluzunapreguntainteresanteiquestQueacutepasaconlasvariableslocalescuandolafuncioacutenquelascreoacuteyanoestaacuteactiva

ElsiguientecoacutedigomuestraunejemplodeestoDefineunafunncioacutenenvuelveValorquecreaunavariablelocalDespueacutesdevuelveunafuncioacutenqueaccedeydevuelveestavariablelocal

functionenvuelveValor(n)varvariableLocal=nreturnfunction()returnvariableLocal

varenvoltura1=envuelveValor(1)varenvoltura2=envuelveValor(2)consolelog(envoltura11())rarr1consolelog(envoltura2())rarr2

EstoestaacutepermitidoyfuncionacomoesperariacuteaslavariabletodaviacuteapuedeleerseDehechomuacuteltiplesinstanciasdelasvariablespuedenexistiralmismotiempoloqueesotrabuenailustracioacutendelconceptodequelasvariableslocalessonre-creadasrealmenteparacadallamadadiferentesllamadasnopuedenafectarotrasvariableslocales

Estacaracteriacutestica-sercapacesdehacerreferenciaaunainstancialocaldevarablesenunfuncioacutenquelasencierra-sellamaclosureUnafuncioacutenqueencapsulaalgunasvariableslocalesesllamadaunclosureEstecomportamientonosoacuteloteliberadepreocupartedelostiemposdevidadelasvariablesademaacutespermitealgunosusoscreativosdelasfunciones

Conunpequentildeocambiopodemoshacerdelejemploanteriorfuncionesquemultipliquenporunnuacutemeroarbitrario

3Funciones

51

functionmultiplicador(factor)returnfunction(numero)returnnumerofactor

vardoble=multiplicador(2)consolelog(doble(5))rarr10

LavariableexpliacutecitavariableLocaldelafuncioacutenenvuelveValorenelejemploprevionoesnecesariaporqueunparaacutemetroensiacutemismoesunavariablelocal

ConcebirlosparaacutemetrosdeestaformarequierealgodepraacutecticaUnbuenmodelomentalespensarenlapalabraclavefunctioncomosicongelaraelcoacutedigoqueestaacutedentrodeellaenunpaquete(elvalorfuncioacuten)Asiacutecuandoleasreturnfunction()piensaenqueestoregresaunaccesoaunconjuntodecaacutelculoscongeladosparausoposterior

EnelejemplomultiplicadorregresaunpedazocongeladodecoacutedigoqueseguardaenlavariabledobleLauacuteltimaliacuteneaentoncesllamaelvalorguardadoenestavariablehaciendoqueelcoacutedigocongelado(returnnumerofactor)seactiveEstetodaviacuteatieneaccesoalavariablefactordelallamadaamultiplicadorquelocreoacuteyademaacutesobtieneaccesoalargumentoquesepasacuandoseactivaelcoacutedigo5atraveacutesdesuparaacutemetronumero

Recursioacuten

EsperfectamentecorrectoqueunafuncioacutensellameasiacutemismamientrastengacuidadodenodesbordarlapilaUnafuncioacutenquesellamaasiacutemismasellamarecursivaLarecursioacutenpermitequealgunasfuncionesseescribanconunestilodiferenteTomemosporejemploestaimplementacioacutenalternativadepotencia

functionpotencia(baseexponente)if(exponente==0)return1elsereturnbasepotencia(baseexponente-1)

consolelog(potencia(23))rarr8

EstoesmaacutescercanoalmodoenquelosmatemaacuteticosdefinenlapotenciacioacutenydescribeelconceptodeunmodomaacuteselegantequelavariantequelohaceconbuclesLafuncioacutensellamaasiacutemismavariasvecescondiferentesargumentosparaconseguirlamultiplicacioacuten

3Funciones

52

repetida

PeroestaimplementacioacutentieneunproblemaimportanteenimplementacionestiacutepicasdeJavaScriptescercade10vecesmaacuteslentaquelaversioacutenconbuclesCorreratraveacutesdeunsiplebucleesmaacutesbaratoquellamaraunafuncioacutenmuchasveces

EldilemadevelocidadcontraeleganciaesinteresantePuedesverlocomounaluchacontinuaentreamigabilidad-humanoyamigabilidad-maacutequinaCasicualquierprogramapuedehacersemaacutesraacutepidohacieacutendolomaacutesgrandeyconvolucionadoElprogramadordebededecidirelbalanceapropiado

Enelcasodelafuncioacutenanteriorpotencialapocoeleganteversioacuten(iterativa)esauacutenbastantesimpleyfaacutecildeleerNotienemuchosentidoreemplazarlaconlaversioacutenrecursivaAmenudosinembargounprogramatieneconceptostancomplejosquesacrificarunpocodeeficienciaparahacerelprogramamaacutesclarosevuelveunaopcioacutenatractiva

LareglabaacutesicaquehasidorepetidapormuchosprogramadoresyconlacuaacutelconcuerdodetodocorazoacutenesnopreocuparseporlaeficienciahastaqueesteacutesseguroqueelprogramaesdemasiadolentoSiloesbuscalaspartesqueestaacutenabarcandolamayoriacuteadeltiempoyempiezaacambiareleganciaporeficienciaenesaspartes

PorsupuestoestareglanosignificaquedebasignorarelrendimientocompletamenteEnmuchoscasoscomoenlafuncioacutenpotencianoseganademasiadasimplicidaddelasolucioacuteneleganteYavecesunprogramadorexperimentadopuedeverdeinmediatoqueunenfoquesencillonuncavaaserlosuficientementeraacutepido

LarazoacutenporlaqueestoyhablandotantodeestoesquemuchosprogramadoresnovatosseenfocanfanaacuteticamenteenlaeficienciainclusoenlosdetallesmaacutespequentildeosElresultadosonprogramasmaacutesgrandesmaacutescomplicadosyamenudomenoscorrectosquetomanmaacutestiempoenescribirsequesusequivalentesmaacutessencillosyquegeneralmentecorrensolounpocomaacutesraacutepido

PerolarecursioacutennoessiempresoacutelounaalternativamenoseficientealosbuclesAlguosproblemassonmuchomaacutesfaacutecilesderesolverconrecursioacutenqueconbuclesLamayoriacuteadeestossonproblemasquerequierenexploraroprocesarvariasramascadaunadelascuaacutelessepuederamificarotravez

Consideraelsiguenterompecabezasempezandoporelnuacutemero1yantildeadiendorepetidamente5omultiplicaacutendolopor3unnuacutemeroinfinitodenuevosnuacutemerospuedeserproducidoiquestCoacutemoescribiriacuteasunafuncioacutenquedadounnuacutemerotratedeencontrarunasecuenciadesumasymultipliclacionesqueproducenesenuacutemeroPorejemploelnuacutemero13puedeserproducidoalmultiplicarpor3primeroydespueacutessumar5dosvecesmientrasqueelnuacutemero15nopuedeserproducido

3Funciones

53

Aquiacutehayunasolucioacutenrecursiva

functionencontrarSolucion(objetivo)functionencontrar(iniciohistoria)if(inicio==objetivo)returnhistoriaelseif(iniciogtobjetivo)returnnullelsereturnencontrar(inicio+5(+historia++5))||encontrar(inicio3(+historia+3))returnencontrar(11)

consolelog(encontrarSolucion(24))rarr(((13)+5)3)

NotaqueesteprogramanoencuentranecesariamentelarutamaacutescortadeoperacionesSesatisfacecuandocuentrecualquiersequencia

NonecesariamenteesperoqueveascomoestetrabajaestoinmediatamentePerotrabajemosenesoporqueesungranejercicioenelpensamientorecursivo

LafuncioacuteninternaencontrarhacelarecursividadTomadosargumentosndashelnuacutemeroactualyunacadenaqueregistracomohemosalcanzadoelnuacutemerondashyregresaunacadenaquemuestracomollegaralobjetivoonull

ParahacerestolafuncioacutenrealizaunadetresaccionesSielnuacutemeroactualeselnuacutemeroobjetivoentonceslahistoriaactualesunaformadealcanzaresteobjetivoasiacutequesiemplementeesdevueltaSielnuacutemeroactualesmayorqueelnuacutemeroobjetivonotienesentidoseguirhaciendomaacutesexploracionesporquetantosumarcomomultiplicarsoacuteloharaacutemayorelnuacutemeroYfinalmentesiestamostodaviacuteadebajodelobjetivolafuncioacutenpruebalosdoscaminosposiblesqueempiezanconelnuacutemeroactualllamaacutendosedosvecesasiacutemismaunavezporcadaunodelospasospermitosSilaprimerallamadaregresacualquiercosaquenoseanullsedevuelvecomoresultadoDeotraformalasegundaopcioacuteneslaquesedevuelveindependientementedesiproduceunacadenaonull

Paraentendermejorcomoestafuncioacutenproduceelefectoqueestamosbuscandomiremosatodaslasllamadasaencontrarquesehacencuandoestamosbuscandolasolucioacutenparaelnuacutemero13

3Funciones

54

encuentra(11)encuentra(6(1+5))encuentra(11((1+5)+5))encuentra(16(((1+5)+5)+5))demasiadograndeencuentra(33(((1+5)+5)3))demasiadograndeencuentra(18((1+5)3))demasiadograndeencuentra(3(13))encuentra(8((13)+5))encuentra(13(((13)+5)+5))iexclEncontrado

Elsangrado(indentacioacuten)indicalaprofundidadenlapiladellamadasLaprimeravezqueencuentraesllamadasellamadosvecesasiacutemismaparaexplorarlassolucionesqueempiezancon(1+5)y(13)Laprimerallamadaintentaencontrarunasolucioacutenqueempiececon(1+5)yusandolarecursioacutenexploratodaslassolucioacutenesqueproduzcanunnuacutemeromenoroigualqueelnuacutemerobuscadoDadoquenoencuentraunasolucioacutenquecorrespondaconelobjetivoregresanullalaprimerallamadaEntonceseloperador||hacequelallamadaqueexplora(13)sucedaEstabuacutesquedatienemaacutessuertedebidoaquesuprimerallamadarecursivaatraveacutesdeotrallamadarecursivallegaalnuacutemeroquebuscamos13Estallamadarecursuvalamaacutesinternaregresaunacadenaycadaunodelosoperadores||enlallamadasuperiorinmediatapasanesacadenafinalmenteregresandonuestrasolucioacuten

Funcionescrecientes

Existendosformasmaacutesomenosnaturalesdeintorducirlasfuncionesenlosprogramas

LaprimeraesqueteencuentrasatimismoescribiendoelmismocoacutedigovariasvecesNecesitamosevitarhaceresodebidoaquemaacutescoacutedigosignificamaacutesespacioparaqueloserroresseocultenymaacutesmaterialparaqueleerparalaspersonasquequiereentenderelprogramaAsiacutequetomamosfuncionalidadrepetidaencontramosunbuennombreparaestaylaponemosdentrodeunafuncioacutenLasegundaformaesqueencuentresquenecesitasciertafuncionalidadquenohasescritoauacutenyquesuenacomoaquemerecesupropiafuncioacutenEmpezaraacutespornombrarlafuncioacutenydespueacutesescribiraacutessucuerpoPodriacuteasinclusoempezaraescribirelcoacutedigoqueusalafuncioacutenantesderealmentedefinirlafuncioacutenmisma

QueacutetandifiacutecilesencontrarunnombreparaunafuncioacutenesunbuenindicadordequetanclarotieneselconceptodeaquelloqueestaacutestratandodeenvolverHagamosunejemplo

3Funciones

55

NecesitamosescribirunproblemaqueimprimadosnuacutemeroselnuacutemerodelasvacasydelospollosdeunagranjaconlaspalabrasVacasyPollosdespueacutesdeestosycompletadosconcerosparaquesiempreseande3diacutegitosdelongitud

007Vacas011Pollos

EstoclaramenterequiereunafuncioacutendedosargumentosEmpecemosaprogramar

functionimprimeInventarioGranja(vacaspollos)varvacasString=String(vacas)while(vacasStringlengthlt3)vacasString=0+vacasStringconsolelog(vacasString+Vacas)varpollosString=String(pollos)while(pollosStringlengthlt3)pollosString=0+pollosStringconsolelog(pollosString+Pollos)imprimeInventarioGranja(711)

AntildeadirlengthdespuesdeunvalordecadenanosdaraacutelalongituddeesacadenaAsiacuteloswhilecontinuaacutenagregandocerosalprincipiodelacadenadelnuacutemerohastaquesonporlomenosde3caracteres

iexclMisioacutencumplidaPerocasicuandolevamosamandarelcoacutedigoalgranjero(conunabuenafactura)nosllamaynosdicequehaempezadoacriacutearpuercosyquesipodriacuteamosextenderelsoftwareparatambieacutenmostrarlospuerquitosiquestporfavor

DeseguropodemosPeromientrasestamosenelprocesodecopiarypegaresascuatroliacuteneasunavezmaacutesparamosyreconsideramosExisteunamejorformaAquiacutehayunintento

3Funciones

56

functionimprimeConCerosYEtiqueta(numeroetiqueta)varnumeroString=String(numero)while(numeroStringlengthlt3)numeroString=0+numeroStringconsolelog(numeroString++etiqueta)

functionimprimeInventarioGranja(vacaspollospuercos)imprimeConCerosYEtiqueta(vacasVacas)imprimeConCerosYEtiqueta(pollosPollos)imprimeConCerosYEtiqueta(puercosPuercos)

imprimeInventarioGranja(7113)

iexclFuncionaPeroesenombreimprimeConCerosYEtiquetaesunpocofeoAmontonatrescosasndashimprimircompletarconcerosyagragarlaetiquetandashenunasolafuncioacuten

Envezdequitarlaparterepetidadenuestraprogramapormayoreotratemosdeescogerunsoloconcepto

functionrellenoConCero(numeroancho)varcadena=String(numero)while(cadenalengthltancho)cadena=0+cadenareturncadena

functionimprimeInvantarioGranja(vacaspollospuercos)consolelog(rellenoConCero(vacas3)+Vacas)consolelog(rellenoConCero(pollos3)+Pollos)consolelog(rellenoConCero(puercos3)+Puercos)

imprimeInvantarioGranja(7163)

UnafuncioacutenconunbonitoyobvionombrecomorellenoConCerohacemaacutesfaacutecilparaalguienqueleaelcoacutedigodescubrirloquehaceYesoesuacutetilenmaacutessituacionesquesoacuteloenesteprogramaespeciacuteficoPorejemplopuedesusarlaparaimprimirunatablabienalineadadenuacutemeros

iquestQueacutetaninteligenteyversaacutetildeberiacuteasernuestrafuncioacutenPodriacuteamosescribircualquiercosadesdeunafuncioacutenterriblementesimplequesoacutelamenterellenaunnuacutemerodetalmaneraquetenga3caractereshastaunacomplicadamuygeneralizadafuncioacutenunsistemadeformateodenuacutemerosquemanejefraccionesnuacutemerosnegativosalineacioacutendepuntosrellenocondiferentescarecteresyasiacuteporelestilo

3Funciones

57

UnprincipiouacutetilnoantildeadircaracteriacutesticasamenosqueesteacutescompletamentesegurodequelasvasaocuparPuedesertentadorescribirmarcosdetrabajogenerals_framework_sparacadapequentildeopedazodefuncionalidadqueteencuentrasResisteelimpulsoNoacabaraacutesninguacutentrabajorealyterminaraacutesescribiendomuchocoacutedigoquenadieusaraacutealgunavez

Funcionesyefectoscolaterales

Lasfuncionespuedensermaacutesomenosdivididasenaquellasquesonllamadasporsusefectoscolateralesyaquellasquesonllamadasporsuvalorderesultado(Aunqueescompletamenteposibletenertantoefectoscolateralescomoretornarunvalor)

LaprimerfuncioacutendeayudaenelejemplodelagranjaimprimeConCerosYEtiquetaesllamadaporsuefectocolateralimprimesuvalorderesultadoLasegundaversioacutenrellenoConCeroesllamadaporsuvalorderesultadoNoescoincidenciaquelasegundaseauacutetilenmaacutessituacionesquelaprimeraLasfuncionesquecreanvaloressonmaacutesfaacutecilesdecombinarennuevasformasquefuncionesquerealizandirectamenteunefectocolateral

UnafuncioacutenpuraesuntipodefuncioacutenqueproduceunvalorquenosoacutelocarecedeefectoscolateralestampocousalosefectoscolateralesdeotrocoacutedigondashporejemplonoleevariablesglobalesquesonocasionalmentecambiadasporotrocoacutedigoUnafuncioacutenpuratienelaagradablepropiedaddequecuandosellamaalosmismosargumentossiempreproduceelmismovalor(ynohacenadamaacutes)EstohacefaacutecilrazonarconellaUnallamadaaunafuncioacutencomoestapuedesersustituidamentalmentecomosuresultadosincambiarelsignificadodelcoacutedigoCuandonoestassegurodequeunafuncioacutenpurafuncionacorrectamentepuedesprobarlosimplementellamaacutendolaysabiendoquetrabajabienestecontextotrabajaraacutebienencualquiercontextoFuncionesnopuraspuedenregresardiferentesvaloresbasadasentodotipodefactoresytienenefectossecundariosyquepuedenserdifiacutecildeprobaryderazonarconellas

AuacutenasiacutenohaynecesidaddesentirsemalcuandoescribimosfuncionesquenosonpurasodearmarunaguerrasantaparaeliminarlasdetucoacutedigoLosefectossecundariosamenudosonuacutetilesNohabriacuteaformadeimprimirunaversioacutenpuradeconsolelogporejemployconsolelogesciertamenteuacutetilAlgunasoperacionessonademaacutesmaacutesfaacutecilesdeexpresarenunaformaeficientecuandoseusanlosefectossecundariosasiacutequelavelocidaddecoacutemputopuedeserunarazoacutenparaevitarlapureza

Resumen

EstecapiacutetuloseensentildeoacutecomoescribirtuspropiasfuncionesLapalabraresevadafunctioncuandoseusacomounaexpresioacutenpuedecrearunvalorfuncioacutenCuandoesusadacomosentenciapuedeserusadaparadeclararunavariableydarleunafuncioacuten

3Funciones

58

comovalor

Crearunvalorfuncioacutenfvarf=function(a)consolelog(a+2)

Declarargcomofuncioacutenfunctiong(ab)returnab35

UnaspectoclaveparaentenderlasfuncionesesentenderlosaacutembitoslocalesLosparaacutemetrosyvariablesdeclaradasdentrodeunafuncioacutensonlocalesparalafuncioacutenre-creadoscadavezquelafuncioacutenesllamadaynovisiblesdedesdefueraLasfuncionesdeclaradasdentrodeotrafuncioacutentienenaccesoalaacutembitolocalexternodelafuncioacuten

SepararlastareasquetutarearealizaendiferentesfuncionesesuacutetilNotendraacutesquerepetirlomismotantoylasfuncionespuedenhacerunprogramamaacuteslegiblealagruparelcoacutedigoenpartesconceptualesdelamismaformaquecapiacutetulosyseccionesayudanaorganizareltextoregular

Ejercicios

Miacutenimo

ElcapiacutetuloanteriorintordujolafuncioacutenestaacutendarMathminquedevuelvesuargumentomaacutespequentildeoAhoranosotrosmismospodemoshaceresoEscribeunafuncioacutenminquetomedosargumentosydevuelvaelmiacutenimo

Tucoacutedigovaaquiacute

consolelog(min(010))rarr0consolelog(min(0-10))rarr-10

pista

Sitienesproblemasponiendolasllavesylospareacutentesisenellugarcorrectoparaobtenerunadefinicioacutendefuncioacutenvaacutelidaempiezaporcopiarunodelosejemplosdelcapiacutetuloymodificarlo

Unafuncioacutenpuedecontenermuacuteltiplesreturn

3Funciones

59

Recursioacuten

Hemosvistoque(eloperadordesobrante)puedeserusadoparaprobarsiunnuacutemeroesparoimparusando2parachecarsiesdivisiblepordosAquiacutehayotraformadedefinirsiunnuacutemeroenteroesparoimpar

CeroesparUnoesimparParacualquierotronuacutemeroNsuparidadeslamismaqueN-2

EscribeunafuncioacutenrecursivaesParquecorrespondaaestadescripcioacutenLafuncioacutendeberiacuteaaceptarunnumerocomoparaacutemetroyregresarunBooleano

Pruebalacon50y75Observacoacutemosecomportacon-1iquestPorqueacuteiquestPuedespensarenalgunaformadearreglaresto

Tucoacutedigovaaquiacute

consolelog(esPar(50))rarrtrueconsolelog(esPar(75))rarrfalseconsolelog(esPar(-1))rarr

pista

LafuncioacutenseraacutealgosimilaralencuentrainternoenlasolucioacutenrecursivaencuentraSolucionenestecapiacutetuloconunacadenadeifelseifelsequeprobaraacutecuaacuteldelostrescasosaplicaElelsefinalcorrespondientealtercercasohacelallamadarecursivaCadaunadelasramasdebedecontenerunasentenciareturnodealgunaotraformaarreglaacuterselasparadevolverunvalorespeciacutefico

CuandoseledaunnuacutemeronegativolafuncioacutenvaallamarseasiacutemismaunayotravezpasaacutendoseunnuacutemerocadavezmaacutesnegativoasiacutealejaacutendosemaacutesymaacutesderegresarunasolucioacutenEnalguacutenmomentosequedaraacutesinespacioenlapilayabortaraacute

ContandoFrijoles

Puedesobtenereln-avocaracteroletradeunacadenaescribiendocadenacharAt(N)similaracomoobtienessulongitudconcadenalengthElvalorobtenidoseraacuteunacadenaquecontienesoacutelouncaracter(porejemplob)Elprimercaractertienela

3Funciones

60

posicioacutencerolocualhacequeeluacuteltimopuedaserencontradoenlaposicioacutenstringlenght-1Enotraspalabrasunacadenasdedoscaracterestieneunldquolenghtrdquoolongitudde2ysuscaracterestienenlasposiciones0y1

EscribeunafuncioacutencuentaFsquetomeunacadenacomosuuacutenicoargumentoyregreseunnuacutemeroqueindiquecunaacutentoscaracteresldquoFrdquomayuacutesculahayenlacadena

AcontinuacioacutenescribeunafuncioacuteonllamadacuentaCaracterquesecomoportecomocuentaFsconladiferenciadequetomeunsegundocaracterqueindiqueelcaracterqueseraacutecontado(envezdesoacutelocaracteresldquoFrdquo)ReescribecuentaFsparahacerusodeestanuevafuncioacuten

Tucoacutedigovaaaquiacute

consolelog(cuentaFs(FFC))rarr2consolelog(cuentaCaracter(ferrocarrilr))rarr4

pista

Unbucleentufuncioacutentendraacutequerevisarcadacaracterenlacadenacorriendouniacutendicedesdecerohastaunomenosquesulongitud(ltcadenalength)SielcaracterdelaposicioacutenactualeselmismoquelafuncioacutenestaacutebuscandoantildeadeunoalavariablecontadorUnavezquesehaterminadoelbucleelcontadorpuedeserregresado

Ponatencioacutenenhacertodaslasvariablesusadasenlafuncioacutenlocalesalafuncioacutenmidianteelusodelapalabrareservadavar

3Funciones

61

EstructurasdeDatosObjetosyArreglosEndosocasionesmepreguntaron-ldquoDisculpeSrBabbagesipongonuacutemerosincorrectosenlamaacutequinaiquestvanasalirlasrespuestascorrectasrdquo[]NopuedoterminardecomprendereltipodeconfusioacutendeideasquepodriacuteanprovocarestapreguntaCharlesBabbagePassagesfromtheLifeofaPhilosopher(1864)

NuacutemerosBooleanosycadenassonlosladrillosdelosqueestaacutenhechaslasestructurasdedatosPeronopodraacutesconstruirmuchacasadeunsololadrilloLosobjetosnospermitenagruparvalores-incluyendootrosobjetos-permitieacutendonosconstruirestructurasmaacutescomplejas

LosprogramasquehemosconstruidohastaahorahansidoseriamentelimitadosdebidoalhechodequeestabanoperandouacutenicamenteentiposdedatossimplesEstecapiacutetuloagregaraacuteatucajadeherramientasunentendimientobaacutesicodelasestructurasdedatosAlfinalizarlosabraacuteslosuficienteparaempezaraescribiralgunosprogramasdeutilidad

ElcapiacutetulotrabajaraacutealolargodeunejemplodeprogramacioacutenmaacutesomenosrealistaintroduciendoconceptosconformeapliquenalproblemaencuestioacutenElcoacutedigodeejemplomuchasvecesseconstruiraacutesobrefuncionesyvariablesquefueronpresentadaspreviamenteeneltexto

ElsandboxdeprogramacioacutenenliacuteneaparaellibroeloquentjavascriptnetcodeproporcionaunamaneradecorrerelcoacutedigoenelcontextodeuncapiacutetuloenespaciacuteficoSidecidestrabajarenlosejemplosenotroentornoaseguacuteratededescargarprimeroelcoacutedigocompletodeestecapiacutetulodesdelapaacuteginadelsandbox

Laardillalobo

DevezencuandocomuacutenmenteentrelasochoylasdiezdelanocheJacquessetransformaenunpequentildeoypeludoroedorconunafrondosacola

PorunladoJacquesestabastantecontentodenotenerlaclaacutesicalicantropiacuteaConvertirseenunaardillasuelecausarmenosproblemasqueconvertirseenunloboEnvezdetenerquepreocuparseporcomerseaccidentalmenteaunvecino(esoseriacuteaextrantildeo)lepreocupaelserdeboradoporelgatodelvecinoDespueacutesdeunpardeocasionesdondesedespertoacutedesnudoydesorientadoenunaapenasdelgadaramaenlacimadeunroblesehaaseguradodecerrarpuertasyventanasdesucuartoporlasnochesyponeralgunasnuecesenelsueloparamantenerseocupado

4EstructurasdeDatosObjetosyArreglos

62

EsoresuelvelosproblemasdelgatoyelroblePeroJacquesauacutensufredesuenfermedadLosmomentosirregularesenquesepresentalatransformacioacutenlehacensospecharquepudieranserdetonadasporalgoPoralguacutentiempocreyoacutequesucediacuteasoacuteloenlosdiasquehabiacuteatocadoaacuterbolesAsiacutequedejoacutedetocaraacuterbolesdemaneradefinitivaeinclusoevitoacuteacercarseaellosPeroelproblemapresistioacute

CambiandoaunaperspectivaunpocomaacutescientiacuteficaJacquesplaneaempezarunregistrodiariodetodoloquehizoesediacuteaysituvoonounatransformacioacutenConestosdatosesperalimitarlascondicionesquedisparanlastransformaciones

Laprimercosaquehaceesdisentildearunaestructuradedatosparaalmacenarestainformacioacuten

Conjuntosdedatos

ParatrabajarconunpedazodedatosdigitalesprimerotendremosqueencontrarunaformaderepresentarloenlamemoriadenuestramaacutequinaDigamoscomounpequentildeoejemploquequeremosrepresentarunacoleccioacutendenuacutemeros2357y11

Podriacuteamosponernoscreativosusandocadenas-despuesdetodolascadenaspuedenserdecualquierlongitudasiacutequepodriacuteamosponemuchainformacioacutenenellas-yusar235711comonuestrarepresentacioacutenPeroestoesextrantildeoDealgunaformatendriacuteasqueextaerlosdiacutegitosyconvertirlosdevueltaanuacutemerosparaaccesarlos

AfortunadamenteJavascriptproporcionauntipodedatoespeciacuteficoparaalmacenarsecuenciasdevaloresSelellamaarregloyseescribecomounalistadevaloresentrecorchetesseparadosporcomas

varlistOfNumbers=[235711]consolelog(listOfNumbers[1])rarr3consolelog(listOfNumbers[1-1])rarr2

4EstructurasdeDatosObjetosyArreglos

63

LanotacioacutenparaobtenerloselementosdentrodeunarreglotambieacutenutilizacorchetesUnpardecorchetesinmediaacutetamentedespueacutesdeunaexpresioacutenconotraexpresioacutendentrodeloscorchetesbuscaraacuteelelementoenlaexpresioacutendelaizquierdaquecorrespondaaliacutendicedadoporlaexpresioacutenencorchetes

ElprimeriacutendicedeunarregloesceronounoAsiacutequeelprimerelementopuedeleerseusandolistOfNumbers[0]SinotienesantecedentesenprogramacioacutenacostumbrarteaestaconvencioacutenpuedetomartealguacutentiempoPeroelzero-basedcountingtieneunalargatradicioacutenentecnologiacuteaymientraslaconvencioacutensesigademaneraconsistente(quesehahechoenJavascript)funcionabien

Propiedades

HemosvistoalgunasexpresionessospechosascomomyStringlength(paraobtenerlalongituddeunacadena)yMathmax(lafuncioacutenmaacuteximo)enejemplospasadosEstassonexpresionesqueaccesanunapropiedaddealguacutenvalorEnelprimercasoaccesamoslapropiedadlengthdeelvalorenmyStringEnelsegundoaccesamoslapropiedadllamadamaxenelobjetoMath(queesunacoleccioacutendevaloresyfuncionesrelacionadasconlasmatemaacuteticas)

CasitodoslosvaloresdeJavascripttienenpropiedadesLasexcepcionessonnullyundefinedSiintentasaccederunapropiedaddealgunodeestosnonvaluesrecibiraacutesunerror

nulllengthrarrTypeErrorCannotreadpropertylengthofnull

LasdosmanerascomuacutenesdeaccederapropiedadesenJavascriptesconunpuntoyconcorchetesAmbasvaluexyvalue[x]accedenunapropiedadenvaluemdashperononecesariamentelamismapropiedadLadiferenciaradicaencoacutemoseinterpretaxCuandousamosunpuntolapartedespueacutesdelpuntodebeserunnombredevariablevaacutelidoynombrademaneradirectaalapropiedadCuandousamoscorcheteslaexpresioacutendentrodeloscorchetesesevaluadaparaobtenerelnombredelapropiedadMientrasquevaluexbuscalapropiedaddevaluellamadaldquoxrdquovalue[x]intentaevaluarlaexpresioacutenxyusaelresultadocomoelnombredelapropiedad

AsiacutequesisabesquelapropiedadqueteinteresasellamaldquolengthrdquousasvaluelengthSideseasextraerlapropiedadnombradaporelvaloralmacenadoenlavariableiusasvalue[i]Ydebidoaqueelnombredelaspropiedadespuedesercualquiercadenasiquieresaccesarunapropiedadllamadaldquo2rdquooldquoJohnDoerdquodebesutilizarcorchetesvalue[2]

4EstructurasdeDatosObjetosyArreglos

64

orvalue[JohnDoe]Asiacutelohariacuteasinclusosiconoceselnombreprecisodelapropiedaddeantemanoyaquenildquo2rdquonildquoJohnDoerdquosonnombresvaacutelidosdevariablesyporlotantonopuedenaccesarseatravesdelanotacioacutenconpunto

LoselementosenunarreglosealmacenanenpropiedadesDebidoaquelosnombresdeestaspropiedadessonnuacutemerosyusualmentenecesitamosobtenersunombredeunavariabletenemosqueusarlasintaxisdecorchetesparaaccesarlosLapropiedadlengthdeunarreglonosdicecuantoselementoscontieneEstenombredepropiedadesunnombredevariablevaacutelidoyconocemossunombreporanticipadoasiacutequeparaencontrarlalongituddeunarreglocomuacutenmenteescribiremosarraylengthyaqueesmaacutesfaacutecildeescribirquearray[length]

Meacutetodos

Ambosobjetoslascadenasylosarregloscontienenadicionalmentealapropiedadlengthunnuacutemerodepropiedadesquerefierenavaloresdetipofuncioacuten

vardoh=Dohconsolelog(typeofdohtoUpperCase)rarrfunctionconsolelog(dohtoUpperCase())rarrDOH

TodaslascadenastienenunapropiedadtoUpperCaseCuandoesllamadaregresaraacuteunacopiadelacadenaenlaquetodaslasletrashansidoconvertidasamayuacutesculasTambieacutenexistetoLowerCasePuedesadivinarqueesloquehace

CuriosamenteapesardequelallamadaatoUpperCasenopasaningunargumentolafunciondelalgunmodotieneaccesoalacadenaDohelvalorcuyapropiedadhemosllamadoComofuncionaestoesdecritoenelCapitulo6

LaspropiedadesquecontienenfuncionessongeneralmentellamadasmetodosdelvaloralquepertenecenComoldquotoUpperCaseesunmetododeunacadenardquo

Esteejemplodemuestraalgunosdelosmeacutetodosquelosobjetosdetipoarraytienen

4EstructurasdeDatosObjetosyArreglos

65

varmack=[]mackpush(Mack)mackpush(theKnife)consolelog(mack)rarr[MacktheKnife]consolelog(mackjoin())rarrMacktheKnifeconsolelog(mackpop())rarrKnifeconsolelog(mack)rarr[Mackthe]

ElmetodopushpuedeserusadoparaantildeadirvaloresalfinaldeunarregloElmetodopophaceloopuestoremueveelvaloralfinaldelarregloyloretornaUnarreglodecadenaspuedeseraplanadoaunasolacadenaconelmetodojoinElargumentodadoajoindeterminaeltextoqueespegadoentreloselementosdelarreglo

Objetos

DeregresoalaardillaloboUnconjuntoderegistrodeentradaspuedeserrepresentadocomounarregloPerolasentradasnoconsistensolamenteenunnumeroounacadena-cadaentradanecesitaalmacenarunalistadeactividadesyunvalorBooleanoqueindiquesiJacquesseconvirtioacuteenunaardillaIdealmentenosgustariacuteaagruparesosvaloresjuntosenununicovalorydespuesponeresosvaloresagrupadosenunarregloderegistrodeentradas

LosvaloresdeltipoobjectsoncoleccionesarbitrariasdepropiedadesypodemosagregaroeliminaresaspropiedadescomonosparezcaUnamaneradecrearunobjetoesusarnotacioacutendellaves

varday1=squirrelfalseevents[worktouchedtreepizzarunningtelevision]consolelog(day1squirrel)rarrfalseconsolelog(day1wolf)rarrundefinedday1wolf=falseconsolelog(day1wolf)rarrfalse

DentrodelasllavespodemosdarunalistadepropiedadesseparadasporcomasCadapropiedadestaacuteescritacomounnombreseguidapordospuntosseguidaporunaexpresioacutenqueproveeunvalorparalapropiedadLosespaciosysaltosdeliacuteneanosonsignificantes

4EstructurasdeDatosObjetosyArreglos

66

CuandounobjetoabarcamultiplesliacuteneasmarcandoloscomoenelejemploanteriorestomejoralalegibilidaddelcodigoLaspropiedadescuyosnombresnosonnombresvalidosdevariablesonumerosvalidostienenqueserencerradasencomillas

vardescriptions=workWenttoworktouchedtreeTouchedatree

EstosignificaquelasllavestienendossignificadosenJavaScriptAliniciodeunasentenciainicianunbloquedesentenciasEncualquierotraposicioacutendescribenunobjetoAfortunadamentecasiacutenuncaesutiliniciarunadeclaracioacutenconunobjetodetipollaveyenprogramastiacutepicosnohayambiguumledadentreestosdosusos

Leerunapropiedadquenoexisteproduciraacuteelvalorundefinedloquepasolaprimeravezqueintentamosleerlapropiedadloboenelejemploanterior

Esposibleasignarunvaloraunaexpresioacutendetipopropiedadconeloperador=Estoreemplazaraacuteelvalordelapropiedadsiexistiacuteaocrearaacuteunanuevapropiedadenelobjetosinolahabiacutea

ParavolverbrevementeanuestromodelodetentaacuteculosdeasociaciondevariablesAsociacioacutendevariablessimilaresElloscaptanvaloresperootrasvariablesypropiedadespodriacuteanestarllevandoseacaboenlosmismosvaloresTuacutepuedespensarenobjetoscomolospulposconcualquiernuacutemerodetentaacuteculoscadaunodeloscualestieneunnombreinscritoenella

EsunoperadorunitarioquecuandoseaplicaaunaexpresioacutenaccesoalapropiedadeliminaraacutelapropiedadconelnombredelobjetoEstonoesunacosacomuacutenahacerperoesposible

varanObject=left1right2consolelog(anObjectleft)rarr1deleteanObjectleftconsolelog(anObjectleft)rarrundefinedconsolelog(leftinanObject)rarrfalseconsolelog(rightinanObject)rarrtrue

EloperadorbinarioincuandoseaplicaaunacadenayunobjetodevuelveunvalorbooleanoqueindicasieseobjetotieneesapropiedadLadiferenciaentreelestablecimientodeunapropiedadaundefinedyelhechodeeliminarloesqueenel

4EstructurasdeDatosObjetosyArreglos

67

primercasoelobjetotodaviacuteatienelapropiedad(quesimplementenotieneunvalormuyinteresante)mientrasqueenelsegundocasolapropiedadyanoestaacutepresenteydevolveraacutefalso

ArraysthenarejustakindofobjectspecializedforstoringsequencesofthingsIfyouevaluatetypeof[12]thisproducesobjectYoucanseethemaslongflatoctopuseswithalltheirarmsinaneatrowlabeledwithnumbers

imageimgoctopus-arrayjpg[alt=Artistsrepresentationofanarray]

SowecanrepresentJacquesrsquojournalasanarrayofobjects

varjournal=[events[worktouchedtreepizzarunningtelevision]squirrelfalseevents[workicecreamcauliflowerlasagnatouchedtreebrushedteeth]squirrelfalseevents[weekendcyclingbreakpeanutsbeer]squirreltrueandsoon]

==Mutability==

WewillgettoactualprogrammingrealsoonnowButfirsttheresonelastpieceoftheorytounderstand

WeveseenthatobjectvaluescanbemodifiedThetypesofvaluesdiscussedinearlierchapterssuchasnumbersstringsandBooleansareallimmutablemdashitisimpossibletochangeanexistingvalueofthosetypesYoucancombinethemandderivenewvaluesfromthembutwhenyoutakeaspecificstringvaluethatvaluewillalwaysremainthesameThetextinsideitcannotbechangedIfyouhavereferencetoastringthatcontainscatitisnotpossibleforothercodetochangeacharacterinthatstringtomakeitspellrat

Withobjectsontheotherhandthecontentofavaluecanbemodifiedbychangingitsproperties

Whenwehavetwonumbers120and120wecanconsiderthempreciselythesamenumberwhetherornottheyrefertothesamephysicalbitsButwithobjectsthereisadifferencebetweenhavingtworeferencestothesameobjectandhavingtwodifferentobjectsthatcontainthesamepropertiesConsiderthefollowingcode

4EstructurasdeDatosObjetosyArreglos

68

varobject1=value10varobject2=object1varobject3=value10

consolelog(object1==object2)rarrtrueconsolelog(object1==object3)rarrfalse

object1value=15consolelog(object2value)rarr15consolelog(object3value)rarr10

(((tentacle(analogy))))(((variablemodelof)))Theobject1andobject2variablesgraspthesameobjectwhichiswhychangingobject1alsochangesthevalueofobject2Thevariableobject3pointstoadifferentobjectwhichinitiallycontainsthesamepropertiesasobject1butlivesaseparatelife

(((==operator)))(((comparisonofobjects)))(((deepcomparison)))JavaScripts==operatorwhencomparingobjectswillreturntrueonlyifbothobjectsarepreciselythesamevalueComparingdifferentobjectswillreturnfalseeveniftheyhaveidenticalcontentsThereisnoldquodeeprdquocomparisonoperationbuiltintoJavaScriptwhichlooksatobjectscontentsbutitispossibletowriteityourself(whichwillbeoneofthelink04_datahtmlexercise_deep_compare[exercises]attheendofthischapter)

==Thelycanthropeslog==

(((weresquirrelexample)))(((lycanthropy)))(((addEntryfunction)))SoJacquesstartsuphisJavaScriptinterpreterandsetsuptheenvironmentheneedstokeephis((journal))

include_code

varjournal=[]

functionaddEntry(eventsdidITurnIntoASquirrel)journalpush(eventseventssquirreldidITurnIntoASquirrel)

Andtheneveryeveningattenmdashorsometimesthenextmorningafterclimbingdownfromthetopshelfofhisbookcasemdashherecordstheday

4EstructurasdeDatosObjetosyArreglos

69

addEntry([worktouchedtreepizzarunningtelevision]false)addEntry([workicecreamcauliflowerlasagnatouchedtreebrushedteeth]false)addEntry([weekendcyclingbreakpeanutsbeer]true)

Oncehehasenoughdatapointsheintendstocomputethe((correlation))betweenhissquirrelificationandeachofthedayseventsandideallylearnsomethingusefulfromthosecorrelations

(((correlation)))Correlationisameasureof((dependence))between((variable))s(ldquovariablesrdquointhestatisticalsensenottheJavaScriptsense)Itisusuallyexpressedasacoefficientthatrangesfrom-1to1ZerocorrelationmeansthevariablesarenotrelatedwhereasacorrelationofoneindicatesthatthetwoareperfectlyrelatedmdashifyouknowoneyoualsoknowtheotherNegativeonealsomeansthatthevariablesareperfectlyrelatedbutthattheyareoppositesmdashwhenoneistruetheotherisfalse

(((phicoefficient)))Forbinary(Boolean)variablesthephicoefficient(ϕ)providesagoodmeasureofcorrelationandisrelativelyeasytocomputeTocomputeϕweneeda((table))nthatcontainsthenumberoftimesthevariouscombinationsofthetwovariableswereobservedForexamplewecouldtaketheeventofeating((pizza))andputthatinatablelikethis

imageimgpizza-squirrelsvg[alt=Eatingpizzaversusturningintoasquirrelwidth=7cm]

ϕcanbecomputedusingthefollowingformulawherenreferstothetable

ifdefhtml_target[]

++++

ϕ= n n -n nradic

ltdivgt++++

endifhtml_target[]

ifdeftex_target[]

pass[beginequationvarphi=fracn11n00-n10n01sqrtn1bulletn0bulletnbullet1nbullet0endequation]

endiftex_target[]

11 00 10 01n n n n1bull 0bull bull1 bull0

4EstructurasdeDatosObjetosyArreglos

70

Thenotation(htmln~01~)(texpass[$n01$])indicatesthenumberofmeasurementswherethefirstvariable(squirrelness)isfalse(0)andthesecondvariable(pizza)istrue(1)Inthisexample(html_n~01~)(texpass[$n_01$])is9

Thevalue(htmln~1bull~)(texpass[$n1bullet$])referstothesumofallmeasurementswherethefirstvariableistruewhichis5intheexampletableLikewise(html_n~bull0~)(texpass[$n_bullet0$])referstothesumofthemeasurementswherethesecondvariableisfalse

(((correlation)))(((phicoefficient)))Soforthepizzatablethepartabovethedivisionline(thedividend)wouldbe1times76-4times9=40andthepartbelowit(thedivisor)wouldbethesquarerootof5times85times10times80or(htmlradic340000)(texpass[$sqrt340000$])Thiscomesouttoϕasymp0069whichistinyEating((pizza))doesnotappeartohaveinfluenceonthetransformations

==Computingcorrelation==

(((arrayastable)))(((nestingofarrays)))Wecanrepresentatwo-by-two((table))inJavaScriptwithafour-elementarray([76941])Wecouldalsouseotherrepresentationssuchasanarraycontainingtwotwo-elementarrays([[769][41]])oranobjectwithpropertynameslike11and01buttheflatarrayissimpleandmakestheexpressionsthataccessthetablepleasantlyshortWellinterprettheindicestothearrayastwo-((bit))((binarynumber))wheretheleftmost(mostsignificant)digitreferstothesquirrelvariableandtherightmost(leastsignificant)digitreferstotheeventvariableForexamplethebinarynumber10referstothecasewhereJacquesdidturnintoasquirrelbuttheevent(saypizza)didntoccurThishappenedfourtimesAndsincebinary10is2indecimalnotationwewillstorethisnumberatindex2ofthearray

(((phicoefficient)))(((phifunction)))Thisisthefunctionthatcomputestheϕcoefficientfromsuchanarray

testclipinclude_codestrip_log

functionphi(table)return(table[3]table[0]-table[2]table[1])Mathsqrt((table[2]+table[3])(table[0]+table[1])(table[1]+table[3])(table[0]+table[2]))

consolelog(phi([76941]))rarr0068599434

4EstructurasdeDatosObjetosyArreglos

71

(((squareroot)))(((Mathsqrtfunction)))ThisissimplyadirecttranslationoftheϕformulaintoJavaScriptMathsqrtisthesquarerootfunctionasprovidedbytheMathobjectinastandardJavaScriptenvironmentWehavetosumtwofieldsfromthetabletogetfieldslike(htmln~1bull~)(texpass[$n_1bullet$])becausethesumsofrowsorcolumnsarenotstoreddirectlyinourdatastructure

(((JOURNALdataset)))JacqueskepthisjournalforthreemonthsTheresulting((dataset))isavailableinthecodingsandboxforthischapter(book(httpeloquentjavascriptnetcode4[_eloquentjavascriptnetcode4_]))whereitisstoredintheJOURNALvariableandinadownloadablehttpeloquentjavascriptnetcodejacques_journaljs[file]

(((tableForfunction)))(((hasEventfunction)))Toextractatwo-by-two((table))foraspecificeventfromthisjournalwemustloopoveralltheentriesandtallyuphowmanytimestheeventoccursinrelationtosquirreltransformations

include_codestrip_log

functionhasEvent(evententry)returnentryeventsindexOf(event)=-1

functiontableFor(eventjournal)vartable=[0000]for(vari=0iltjournallengthi++)varentry=journal[i]index=0if(hasEvent(evententry))index+=1if(entrysquirrel)index+=2table[index]+=1returntable

consolelog(tableFor(pizzaJOURNAL))rarr[76941]

(((arraysearching)))(((indexOfmethod)))ThehasEventfunctiontestswhetheranentrycontainsagiveneventArrayshaveanindexOfmethodthattriestofindagivenvalue(inthiscasetheeventname)inthearrayandreturnstheindexatwhichitwasfoundor-1ifitwasntfoundSoifthecalltoindexOfdoesntreturn-1thenweknowtheeventwasfoundintheentry

(((arrayindexing)))ThebodyoftheloopintableForfiguresoutwhichboxinthetableeachjournalentryfallsintobycheckingwhethertheentrycontainsthespecificeventitsinterestedinandwhethertheeventhappensalongsideasquirrelincidentTheloopthenaddsonetothenumberinthearraythatcorrespondstothisboxonthetable

4EstructurasdeDatosObjetosyArreglos

72

Wenowhavethetoolsweneedtocomputeindividual((correlation))sTheonlystepremainingistofindacorrelationforeverytypeofeventthatwasrecordedandseewhetheranythingstandsoutButhowshouldwestorethesecorrelationsoncewecomputethem

==Objectsasmaps==

(((weresquirrelexample)))(((array)))Onepossiblewayistostoreallthe((correlation))sinanarrayusingobjectswithnameandvaluepropertiesButthatmakeslookingupthecorrelationforagiveneventsomewhatcumbersomeyoudhavetoloopoverthewholearraytofindtheobjectwiththerightnameWecouldwrapthislookupprocessinafunctionbutwewouldstillbewritingmorecodeandthecomputerwouldbedoingmoreworkthannecessary

[[object_map]](((object)))(((squarebrackets)))(((objectasmap)))(((inoperator)))AbetterwayistouseobjectpropertiesnamedaftertheeventtypesWecanusethesquarebracketaccessnotationtocreateandreadthepropertiesandcanusetheinoperatortotestwhetheragivenpropertyexists

varmap=functionstorePhi(eventphi)map[event]=phi

storePhi(pizza0069)storePhi(touchedtree-0081)consolelog(pizzainmap)rarrtrueconsolelog(map[touchedtree])rarr-0081

(((datastructure)))A((map))isawaytogofromvaluesinonedomain(inthiscaseeventnames)tocorrespondingvaluesinanotherdomain(inthiscaseϕcoefficients)

Thereareafewpotentialproblemswithusingobjectslikethiswhichwewilldiscussinlink06_objecthtmlprototypes[Chapter6]butforthetimebeingwewontworryaboutthose

(((forinloop)))(((forloop)))(((objectloopingover)))WhatifwewanttofindalltheeventsforwhichwehavestoredacoefficientThepropertiesdontformapredictableseriesliketheywouldinanarraysowecannotuseanormalforloopJavaScriptprovidesaloopconstructspecificallyforgoingoverthepropertiesofanobjectItlooksalittlelikeanormalforloopbutdistinguishesitselfbytheuseofthewordin

4EstructurasdeDatosObjetosyArreglos

73

for(vareventinmap)consolelog(Thecorrelationfor+event+is+map[event])rarrThecorrelationforpizzais0069rarrThecorrelationfortouchedtreeis-0081

[[analysis]]==Thefinalanalysis==

(((journal)))(((weresquirrelexample)))(((gatherCorrelationsfunction)))TofindallthetypesofeventsthatarepresentinthedatasetwesimplyprocesseachentryinturnandthenloopovertheeventsinthatentryWekeepanobjectphisthathascorrelationcoefficientsforalltheeventtypeswehaveseensofarWheneverwerunacrossatypethatisntinthephisobjectyetwecomputeitscorrelationandaddittotheobject

testclipinclude_codestrip_log

functiongatherCorrelations(journal)varphis=for(varentry=0entryltjournallengthentry++)varevents=journal[entry]eventsfor(vari=0ilteventslengthi++)varevent=events[i]if((eventinphis))phis[event]=phi(tableFor(eventjournal))returnphis

varcorrelations=gatherCorrelations(JOURNAL)consolelog(correlationspizza)rarr0068599434

(((correlation)))Letsseewhatcameout

testno

for(vareventincorrelations)consolelog(event++correlations[event])rarrcarrot00140970969rarrexercise00685994341rarrweekend01371988681rarrbread-00757554019rarrpudding-00648203724andsoon

4EstructurasdeDatosObjetosyArreglos

74

(((forinloop)))MostcorrelationsseemtolieclosetozeroEatingcarrotsbreadorpuddingapparentlydoesnottriggersquirrel-lycanthropyItdoesseemtooccursomewhatmoreoftenonweekendshoweverLetsfiltertheresultstoshowonlycorrelationsgreaterthan01orlessthan-01

start_codetestno

for(vareventincorrelations)varcorrelation=correlations[event]if(correlationgt01||correlationlt-01)consolelog(event++correlation)rarrweekend01371988681rarrbrushedteeth-03805211953rarrcandy01296407447rarrwork-01371988681rarrspaghetti02425356250rarrreading01106828054rarrpeanuts05902679812

A-haTherearetwofactorswhose((correlation))isclearlystrongerthantheothersEating((peanuts))hasastrongpositiveeffectonthechanceofturningintoasquirrelwhereasbrushinghisteethhasasignificantnegativeeffect

InterestingLetstrysomething

include_codestrip_log

for(vari=0iltJOURNALlengthi++)varentry=JOURNAL[i]if(hasEvent(peanutsentry)ampamphasEvent(brushedteethentry))entryeventspush(peanutteeth)consolelog(phi(tableFor(peanutteethJOURNAL)))rarr1

WellthatsunmistakableThephenomenonoccurspreciselywhenJacqueseats((peanuts))andfailstobrushhisteethIfonlyhewerentsuchaslobaboutdentalhygienehedhaveneverevennoticedhisaffliction

KnowingthisJacquessimplystopseatingpeanutsaltogetherandfindsthatthiscompletelyputsanendtohistransformations

(((weresquirrelexample)))AlliswellwithJacquesforawhileButafewyearslaterheloseshis((job))andiseventuallyforcedtotakeemploymentwitha((circus))whereheperformsasTheIncredibleSquirrelmanbystuffinghismouthwithpeanutbutterbeforeeveryshow

4EstructurasdeDatosObjetosyArreglos

75

OnedayfedupwiththispitifulexistenceJacquesfailstochangebackintohishumanformhopsthroughacrackinthecircustentandvanishesintotheforestHeisneverseenagain

==Furtherarrayology==

(((arraymethods)))(((method)))BeforefinishingupthischapterIwanttointroduceyoutoafewmoreobject-relatedconceptsWellstartbyintroducingsomegenerallyusefularraymethods

(((pushmethod)))(((popmethod)))(((shiftmethod)))(((unshiftmethod)))Wesawpushandpopwhichaddandremoveelementsattheendofanarraylink04_datahtmlarray_methods[earlier]inthischapterThecorrespondingmethodsforaddingandremovingthingsatthestartofanarrayarecalledunshiftandshift

vartodoList=[]functionrememberTo(task)todoListpush(task)functionwhatIsNext()returntodoListshift()functionurgentlyRememberTo(task)todoListunshift(task)

(((taskmanagementexample)))ThepreviousprogrammanageslistsoftasksYouaddtaskstotheendofthelistbycallingrememberTo(eat)andwhenyourereadytodosomethingyoucallwhatIsNext()toget(andremove)thefrontitemfromthelistTheurgentlyRememberTofunctionalsoaddsataskbutaddsittothefrontinsteadofthebackofthelist

(((arraysearching)))(((indexOfmethod)))(((lastIndexOfmethod)))TheindexOfmethodhasasiblingcalledlastIndexOfwhichstartssearchingforthegivenelementattheendofthearrayinsteadofthefront

consolelog([12321]indexOf(2))rarr1consolelog([12321]lastIndexOf(2))rarr3

BothindexOfandlastIndexOftakeanoptionalsecondargumentthatindicateswheretostartsearchingfrom

4EstructurasdeDatosObjetosyArreglos

76

(((slicemethod)))(((arrayindexing)))AnotherfundamentalmethodisslicewhichtakesastartindexandanendindexandreturnsanarraythathasonlytheelementsbetweenthoseindicesThestartindexisinclusivetheendindexexclusive

consolelog([01234]slice(24))rarr[23]consolelog([01234]slice(2))rarr[234]

(((stringindexing)))WhentheendindexisnotgivenslicewilltakealloftheelementsafterthestartindexStringsalsohaveaslicemethodwhichhasasimilareffect

(((concatenation)))(((concatmethod)))Theconcatmethodcanbeusedtogluearraystogethersimilartowhatthe+operatordoesforstringsThefollowingexampleshowsbothconcatandsliceinactionIttakesanarrayandanindexanditreturnsanewarraythatisacopyoftheoriginalarraywiththeelementatthegivenindexremoved

functionremove(arrayindex)returnarrayslice(0index)concat(arrayslice(index+1))consolelog(remove([abcde]2))rarr[abde]

==Stringsandtheirproperties==

(((stringproperties)))WecanreadpropertieslikelengthandtoUpperCasefromstringvaluesButifyoutrytoaddanewpropertyitdoesntstick

varmyString=FidomyStringmyProperty=valueconsolelog(myStringmyProperty)rarrundefined

ValuesoftypestringnumberandBooleanarenotobjectsandthoughthelanguagedoesntcomplainifyoutrytosetnewpropertiesonthemitdoesntactuallystorethosepropertiesThevaluesareimmutableandcannotbechanged

(((stringmethods)))(((slicemethod)))(((indexOfmethod)))(((stringsearching)))Butthesetypesdohavesomebuilt-inpropertiesEverystringvaluehasanumberofmethodsThemostusefulonesareprobablysliceandindexOfwhichresemblethearraymethodsofthesamename

4EstructurasdeDatosObjetosyArreglos

77

consolelog(coconutsslice(47))rarrnutconsolelog(coconutindexOf(u))rarr5

OnedifferenceisthatastringsindexOfcantakeastringcontainingmorethanonecharacterwhereasthecorrespondingarraymethodlooksonlyforasingleelement

consolelog(onetwothreeindexOf(ee))rarr11

(((whitespace)))(((trimmethod)))Thetrimmethodremoveswhitespace(spacesnewlinestabsandsimilarcharacters)fromthestartandendofastring

consolelog(okayntrim())rarrokay

(((lengthpropertyforstring)))(((charAtmethod)))(((stringindexing)))WehavealreadyseenthestringtypeslengthpropertyAccessingtheindividualcharactersinastringcanbedonewiththecharAtmethodbutalsobysimplyreadingnumericpropertieslikeyouddoforanarray

varstring=abcconsolelog(stringlength)rarr3consolelog(stringcharAt(0))rarraconsolelog(string[1])rarrb

[[arguments_object]]==Theargumentsobject==

(((argumentsobject)))(((lengthproperty)))(((parameter)))(((optionalargument)))(((array-likeobject)))WheneverafunctioniscalledaspecialvariablenamedargumentsisaddedtotheenvironmentinwhichthefunctionbodyrunsThisvariablereferstoanobjectthatholdsalloftheargumentspassedtothefunctionRememberthatinJavaScriptyouareallowedtopassmore(orfewer)argumentstoafunctionthanthenumberofparametersthefunctionitselfdeclares

functionnoArguments()noArguments(123)ThisisokayfunctionthreeArguments(abc)threeArguments()Andsoisthis

4EstructurasdeDatosObjetosyArreglos

78

(((lengthproperty)))TheargumentsobjecthasalengthpropertythattellsusthenumberofargumentsthatwerereallypassedtothefunctionItalsohasapropertyforeachargumentnamed012andsoon

indexsee[pseudoarrayarray-likeobject](((arraymethods)))IfthatsoundsalotlikeanarraytoyouyourerightitisalotlikeanarrayButthisobjectunfortunatelydoesnothaveanyarraymethods(likesliceorindexOf)soitisalittlehardertousethanarealarray

functionargumentCounter()consolelog(Yougavemeargumentslengtharguments)argumentCounter(StrawmanTautologyAdhominem)rarrYougaveme3arguments

(((journal)))(((consolelog)))(((variadicfunction)))SomefunctionscantakeanynumberofargumentslikeconsolelogThesetypicallyloopoverthevaluesintheirargumentsobjectTheycanbeusedtocreateverypleasantinterfacesForexamplerememberhowwecreatedtheentriestoJacquesrsquojournal

addEntry([worktouchedtreepizzarunningtelevision]false)

Sinceheisgoingtobecallingthisfunctionalotwecouldcreateanalternativethatiseasiertocall

functionaddEntry(squirrel)varentry=events[]squirrelsquirrelfor(vari=1iltargumentslengthi++)entryeventspush(arguments[i])journalpush(entry)addEntry(trueworktouchedtreepizzarunningtelevision)

(((argumentsobjectindexing)))Thisversionreadsitsfirstargument(squirrel)inthenormalwayandthengoesovertherestofthearguments(theloopstartsatindex1skippingthefirst)togatherthemintoanarray

==TheMathobject==

(((Mathobject)))(((Mathminfunction)))(((Mathmaxfunction)))(((Mathsqrtfunction)))(((minimum)))(((maximum)))(((squareroot)))AsweveseenMathisagrab-bagofnumber-relatedutilityfunctionssuchasMathmax(maximum)Mathmin(minimum)andMathsqrt(squareroot)

4EstructurasdeDatosObjetosyArreglos

79

[[namespacepollution]](((namespace)))(((namespacepollution)))(((object)))TheMathobjectisusedsimplyasacontainertogroupabunchofrelatedfunctionalityThereisonlyoneMathobjectanditisalmostneverusefulasavalueRatheritprovidesa_namespacesothatallthesefunctionsandvaluesdonothavetobeglobalvariables

(((variablenaming)))HavingtoomanyglobalvariablesldquopollutesrdquothenamespaceThemorenamesthathavebeentakenthemorelikelyyouaretoaccidentallyoverwritethevalueofsomevariableForexampleitsnotunlikelythatyoullwanttonamesomethingmaxinoneofyourprogramsSinceJavaScriptsbuilt-inmaxfunctionistuckedsafelyinsidetheMathobjectwedonthavetoworryaboutoverwritingit

ManylanguageswillstopyouoratleastwarnyouwhenyouaredefiningavariablewithanamethatisalreadytakenJavaScriptdoesneithersobecareful

(((Mathcosfunction)))(((Mathsinfunction)))(((Mathtanfunction)))(((Mathacosfunction)))(((Mathasinfunction)))(((Mathatanfunction)))(((MathPIconstant)))(((cosine)))(((sine)))(((tangent)))(((PIconstant)))(((pi)))BacktotheMathobjectIfyouneedtodo((trigonometry))MathcanhelpItcontainscos(cosine)sin(sine)andtan(tangent)aswellastheirinversefunctionsacosasinandatanrespectivelyThenumberπ(pi)mdashoratleasttheclosestapproximationthatfitsinaJavaScriptnumbermdashisavailableasMathPI(Thereisanoldprogrammingtraditionofwritingthenamesof((constant))valuesinallcaps)

testno

functionrandomPointOnCircle(radius)varangle=Mathrandom()2MathPIreturnxradiusMathcos(angle)yradiusMathsin(angle)consolelog(randomPointOnCircle(2))rarrx03667y1966

IfsinesandcosinesarenotsomethingyouareveryfamiliarwithdontworryWhentheyareusedinthisbookinlink13_domhtmlsin_cos[Chapter13]Illexplainthem

(((Mathrandomfunction)))(((randomnumber)))ThepreviousexampleusesMathrandomThisisafunctionthatreturnsanewpseudorandomnumberbetweenzero(inclusive)andone(exclusive)everytimeyoucallit

testno

4EstructurasdeDatosObjetosyArreglos

80

consolelog(Mathrandom())rarr036993729369714856consolelog(Mathrandom())rarr0727367032552138consolelog(Mathrandom())rarr040180766698904335

(((pseudorandomnumber)))(((randomnumber)))ThoughcomputersaredeterministicmachinesmdashtheyalwaysreactthesamewayifgiventhesameinputmdashitispossibletohavethemproducenumbersthatappearrandomTodothisthemachinekeepsanumber(orabunchofnumbers)initsinternalstateTheneverytimearandomnumberisrequesteditperformssomecomplicateddeterministiccomputationsonthisinternalstateandreturnspartoftheresultofthosecomputationsThemachinealsousestheoutcometochangeitsowninternalstatesothatthenextldquorandomrdquonumberproducedwillbedifferent

(((rounding)))(((Mathfloorfunction)))IfwewantawholerandomnumberinsteadofafractionalonewecanuseMathfloor(whichroundsdowntothenearestwholenumber)ontheresultofMathrandom

testno

consolelog(Mathfloor(Mathrandom()10))rarr2

Multiplyingtherandomnumberby10givesusanumbergreaterthanorequaltozeroandbelow10SinceMathfloorroundsdownthisexpressionwillproducewithequalchanceanynumberfrom0through9

(((Mathceilfunction)))(((Mathroundfunction)))TherearealsothefunctionsMathceil(forldquoceilingrdquowhichroundsuptoawholenumber)andMathround(tothenearestwholenumber)

==Theglobalobject==

(((globalobject)))(((windowvariable)))(((globalscope)))(((scope)))(((object)))TheglobalscopethespaceinwhichglobalvariableslivecanalsobeapproachedasanobjectinJavaScriptEachglobalvariableispresentasa((property))ofthisobjectIn((browser))stheglobalscopeobjectisstoredinthewindowvariable

testno

4EstructurasdeDatosObjetosyArreglos

81

varmyVar=10consolelog(myVarinwindow)rarrtrueconsolelog(windowmyVar)rarr10

==Summary==

Objectsandarrays(whichareaspecifickindofobject)providewaystogroupseveralvaluesintoasinglevalueConceptuallythisallowsustoputabunchofrelatedthingsinabagandrunaroundwiththebaginsteadoftryingtowrapourarmsaroundalloftheindividualthingsandtryingtoholdontothemseparately

MostvaluesinJavaScripthavepropertiestheexceptionsbeingnullandundefinedPropertiesareaccessedusingvaluepropNameorvalue[propName]ObjectstendtousenamesfortheirpropertiesandstoremoreorlessafixedsetofthemArraysontheotherhandusuallycontainvaryingnumbersofconceptuallyidenticalvaluesandusenumbers(startingfrom0)asthenamesoftheirproperties

TherearesomenamedpropertiesinarrayssuchaslengthandanumberofmethodsMethodsarefunctionsthatliveinpropertiesand(usually)actonthevaluetheyareapropertyof

ObjectscanalsoserveasmapsassociatingvalueswithnamesTheinoperatorcanbeusedtofindoutwhetheranobjectcontainsapropertywithagivennameThesamekeywordcanalsobeusedinaforloop(for(varnameinobject))toloopoveranobjectsproperties

==Exercises==

===Thesumofarange===

(((summing(exercise))))Thelink00_introhtmlintro[introduction]ofthisbookalludedtothefollowingasanicewaytocomputethesumofarangeofnumbers

testno

consolelog(sum(range(110)))

(((rangefunction)))(((sumfunction)))Writearangefunctionthattakestwoargumentsstartandendandreturnsanarraycontainingallthenumbersfromstartupto(andincluding)end

NextwriteasumfunctionthattakesanarrayofnumbersandreturnsthesumofthesenumbersRunthepreviousprogramandseewhetheritdoesindeedreturn55

4EstructurasdeDatosObjetosyArreglos

82

(((optionalargument)))AsabonusassignmentmodifyyourrangefunctiontotakeanoptionalthirdargumentthatindicatestheldquosteprdquovalueusedtobuildupthearrayIfnostepisgiventhearrayelementsgoupbyincrementsofonecorrespondingtotheoldbehaviorThefunctioncallrange(1102)shouldreturn[13579]Makesureitalsoworkswithnegativestepvaluessothatrange(52-1)produces[5432]

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(range(110))rarr[12345678910]consolelog(range(52-1))rarr[5432]consolelog(sum(range(110)))rarr55

endifinteractive_target[]

hint

(((summing(exercise))))(((arraycreation)))(((squarebrackets)))Buildingupanarrayismosteasilydonebyfirstinitializingavariableto[](afreshemptyarray)andrepeatedlycallingitspushmethodtoaddavalueDontforgettoreturnthearrayattheendofthefunction

(((arrayindexing)))(((comparison)))Sincetheendboundaryisinclusiveyoullneedtousethelt=operatorratherthansimplylttocheckfortheendofyourloop

(((argumentsobject)))TocheckwhethertheoptionalstepargumentwasgiveneithercheckargumentslengthorcomparethevalueoftheargumenttoundefinedIfitwasntgivensimplysetittoits((defaultvalue))(1)atthetopofthefunction

(((rangefunction)))(((forloop)))Havingrangeunderstandnegativestepvaluesisprobablybestdonebywritingtwoseparateloopsmdashoneforcountingupandoneforcountingdownmdashbecausethecomparisonthatcheckswhethertheloopisfinishedneedstobegt=ratherthanlt=whencountingdownward

Itmightalsobeworthwhiletouseadifferentdefaultstepnamely-1whentheendoftherangeissmallerthanthestartThatwayrange(52)returnssomethingmeaningfulratherthangettingstuckinan((infiniteloop))

hint

===Reversinganarray===

4EstructurasdeDatosObjetosyArreglos

83

(((reversing(exercise))))(((reversemethod)))(((arraymethods)))ArrayshaveamethodreversewhichchangesthearraybyinvertingtheorderinwhichitselementsappearForthisexercisewritetwofunctionsreverseArrayandreverseArrayInPlaceThefirstreverseArraytakesanarrayasargumentandproducesanewarraythathasthesameelementsintheinverseorderThesecondreverseArrayInPlacedoeswhatthereversemethoddoesitmodifiesthearraygivenasargumentinordertoreverseitselementsNeithermayusethestandardreversemethod

(((efficiency)))(((purefunction)))(((sideeffect)))Thinkingbacktothenotesaboutsideeffectsandpurefunctionsinthelink03_functionshtmlpure[previouschapter]whichvariantdoyouexpecttobeusefulinmoresituationsWhichoneismoreefficient

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(reverseArray([ABC]))rarr[CBA]vararrayValue=[12345]reverseArrayInPlace(arrayValue)consolelog(arrayValue)rarr[54321]

endifinteractive_target[]

hint

(((reversing(exercise))))TherearetwoobviouswaystoimplementreverseArrayThefirstistosimplygoovertheinputarrayfromfronttobackandusetheunshiftmethodonthenewarraytoinserteachelementatitsstartThesecondistoloopovertheinputarraybackwardandusethepushmethodIteratingoveranarraybackwardrequiresa(somewhatawkward)forspecificationlike(vari=arraylength-1igt=0i--)

ReversingthearrayinplaceisharderYouhavetobecarefulnottooverwriteelementsthatyouwilllaterneedUsingreverseArrayorotherwisecopyingthewholearray(arrayslice(0)isagoodwaytocopyanarray)worksbutischeating

Thetrickistoswapthefirstandlastelementsthenthesecondandsecond-to-lastandsoonYoucandothisbyloopingoverhalfthelengthofthearray(useMathfloortorounddownmdashyoudontneedtotouchthemiddleelementinanarraywithanoddlength)andswappingtheelementatpositioniwiththeoneatpositionarraylength-1-iYou

4EstructurasdeDatosObjetosyArreglos

84

canusealocalvariabletobrieflyholdontooneoftheelementsoverwritethatonewithitsmirrorimageandthenputthevaluefromthelocalvariableintheplacewherethemirrorimageusedtobe

hint

[[list]]===Alist===

(((datastructure)))(((list(exercise))))(((linkedlist)))(((object)))(((array)))(((collection)))ObjectsasgenericblobsofvaluescanbeusedtobuildallsortsofdatastructuresAcommondatastructureisthelist(nottobeconfusedwiththearray)Alistisanestedsetofobjectswiththefirstobjectholdingareferencetothesecondthesecondtothethirdandsoon

include_code

varlist=value1restvalue2restvalue3restnull

Theresultingobjectsformachainlikethis

imageimglinked-listsvg[alt=Alinkedlistwidth=6cm]

(((structuresharing)))(((memory)))AnicethingaboutlistsisthattheycansharepartsoftheirstructureForexampleifIcreatetwonewvaluesvalue0restlistandvalue-1restlist(withlistreferringtothevariabledefinedearlier)theyarebothindependentlistsbuttheysharethestructurethatmakesuptheirlastthreeelementsInadditiontheoriginallistisalsostillavalidthree-elementlist

WriteafunctionarrayToListthatbuildsupadatastructurelikethepreviousonewhengiven[123]asargumentandwritealistToArrayfunctionthatproducesanarrayfromalistAlsowritethehelperfunctionsprependwhichtakesanelementandalistandcreatesanewlistthataddstheelementtothefrontoftheinputlistandnthwhichtakesalistandanumberandreturnstheelementatthegivenpositioninthelistorundefinedwhenthereisnosuchelement

(((recursion)))Ifyouhaventalreadyalsowritearecursiveversionofnth

ifdefinteractive_target[]

4EstructurasdeDatosObjetosyArreglos

85

testno

Yourcodehere

consolelog(arrayToList([1020]))rarrvalue10restvalue20restnullconsolelog(listToArray(arrayToList([102030])))rarr[102030]consolelog(prepend(10prepend(20null)))rarrvalue10restvalue20restnullconsolelog(nth(arrayToList([102030])1))rarr20

endifinteractive_target[]

hint

(((list(exercise))))(((linkedlist)))BuildingupalistisbestdonebacktofrontSoarrayToListcoulditerateoverthearraybackward(seepreviousexercise)andforeachelementaddanobjecttothelistYoucanusealocalvariabletoholdthepartofthelistthatwasbuiltsofaranduseapatternlikelist=valueXrestlisttoaddanelement

(((forloop)))Torunoveralist(inlistToArrayandnth)aforloopspecificationlikethiscanbeused

for(varnode=listnodenode=noderest)

CanyouseehowthatworksEveryiterationoftheloopnodepointstothecurrentsublistandthebodycanreaditsvaluepropertytogetthecurrentelementAttheendofaniterationnodemovestothenextsublistWhenthatisnullwehavereachedtheendofthelistandtheloopisfinished

(((recursion)))TherecursiveversionofnthwillsimilarlylookataneversmallerpartoftheldquotailrdquoofthelistandatthesametimecountdowntheindexuntilitreacheszeroatwhichpointitcanreturnthevaluepropertyofthenodeitislookingatTogetthezeroethelementofalistyousimplytakethevaluepropertyofitsheadnodeTogetelementN+1youtaketheNthelementofthelistthatsinthislistsrestproperty

hint

[[exercise_deep_compare]]===Deepcomparison===

(((deepcomparison(exercise))))(((comparison)))(((deepcomparison)))(((==operator)))The==operatorcomparesobjectsbyidentityButsometimesyouwouldprefertocomparethevaluesoftheiractualproperties

4EstructurasdeDatosObjetosyArreglos

86

WriteafunctiondeepEqualthattakestwovaluesandreturnstrueonlyiftheyarethesamevalueorareobjectswiththesamepropertieswhosevaluesarealsoequalwhencomparedwitharecursivecalltodeepEqual

(((null)))(((===operator)))(((typeofoperator)))Tofindoutwhethertocomparetwothingsbyidentity(usethe===operatorforthat)orbylookingattheirpropertiesyoucanusethetypeofoperatorIfitproducesobjectforbothvaluesyoushoulddoadeepcomparisonButyouhavetotakeonesillyexceptionintoaccountbyahistoricalaccidenttypeofnullalsoproducesobject

ifdefinteractive_target[]

testno

Yourcodehere

varobj=hereisanobject2consolelog(deepEqual(objobj))rarrtrueconsolelog(deepEqual(objhere1object2))rarrfalseconsolelog(deepEqual(objhereisanobject2))rarrtrue

endifinteractive_target[]

hint

(((deepcomparison(exercise))))(((typeofoperator)))(((object)))(((===operator)))Yourtestforwhetheryouaredealingwitharealobjectwilllooksomethingliketypeofx==objectampampx=nullBecarefultocomparepropertiesonlywhenbothargumentsareobjectsInallothercasesyoucanjustimmediatelyreturntheresultofapplying===

(((forinloop)))(((inoperator)))UseaforinlooptogooverthepropertiesYouneedtotestwhetherbothobjectshavethesamesetofpropertynamesandwhetherthosepropertieshaveidenticalvaluesThefirsttestcanbedonebycountingthepropertiesinbothobjectsandreturningfalseifthenumbersofpropertiesaredifferentIftheyrethesamethengooverthepropertiesofoneobjectandforeachofthemverifythattheotherobjectalsohasthepropertyThevaluesofthepropertiesarecomparedbyarecursivecalltodeepEqual

(((returnvalue)))Returningthecorrectvaluefromthefunctionisbestdonebyimmediatelyreturningfalsewhenamismatchisnoticedandreturningtrueattheendofthefunction

hint

4EstructurasdeDatosObjetosyArreglos

87

4EstructurasdeDatosObjetosyArreglos

88

FuncionesdeOrderSuperiorTzu-liyTzu-ssuestabanpresumiendoacercadeltamantildeodesusuacutelitmosprogramaslsquoDoscientasmilliacuteneasrsquodijoTzu-lilsquoiexclsincontarloscomentariosrsquoTzu-ssurespondioacutelsquoPsshelmiacuteotieneyacasiunmillioacutendeliacuteneasrsquoElMaestroYuan-MadijolsquoMimejorprogramatienequinientasliacuteneasrsquoOyendoestoTzu-liyTzu-ssufueroniluminadosMasterYuan-MaTheBookofProgramming

HaydosformasdeconstruirundisentildeodesoftwareUnaformaeshacerlotansimplequeobviamentenotengadeficienciasylaotraformaeshacerlotancomplicadoquenohayaobviasdeficieciasCARHoare1980ACMTuringAwardLecture

UnprogramagrandeescostosoynosoacuteloporeltiempoquetomaconstruirloEltamantildeocasisiempreinvolucracomplejidadylacomplejidadconfundealosprogramadoresLosprogramadoresconfundidosasuveztiendenaintroducirerrores(bugs)enlosprogramasUnprogramagrandeademaacutesdaunamplioespacioparaqueestosbugsseocultenhacieacutendolosdifiacutecilesdeencontrar

RegresemosbrevementealosdosprogramasfinalesenlaintroduccioacutenElprimeroesauto-contenidoytieneseisliacuteneasdelongitud

vartotal=0cuenta=1while(cuentalt=10)total+=cuentacuenta+=1consolelog(total)

Elsegundodependededosfuncionesexternasyesunasolaliacutenea

consolelog(suma(rango(110)))

iquestCuaacuteldelosdosesmaacutesprobablequetengaunbug

SicontamoseltamantildeodedefinicioacutendesumayrangoelsegungoprogramatambieacutenesgrandendashinclusomaacutesgrandequeelprimeroPeroauacutenasiacuteyodiriacuteaqueesmaacutesprobablequeseacorrecto

EsmaacutesprobablequeseacorrectoporquelasolucioacutenesexpresadaenunvocabularioquecorrespondealproblemaqueestaacutesiendoresueltoSumarunrangodeenterosnotienequeverconbuclesycontadoresEsacercaderangosysumas

5FuncionesdeOrderSuperior

89

Lasdefinicionesdeestevocabulario(lasfuncionessumayrango)todaviacuteaincluiraacutenbuclescontadoresyotrosdetallesincidentalesPerodebidoaqueestaacutenexpresandoconceptosmaacutessimplesqueelprogramacomountodoesmaacutesfaacutecilacertar

Abstraccioacuten

EnelcontextodelaprogramacioacutenvocabulariosdeesteestilosonusualmentellamadosabstraccioacutenLasabstraccionesecondendetallesynosdanlahabilidaddehablardelosproblemasenunnivelmaacutesalto(omaacutesabstracto)

Comounaanalogiacuteacomparaestasdosrecetasparalasopadeguisantes

`Ponuna1tazadeguisantessecosporpersonaenuncontenedorAgregaaguahastaquelosguisantesesteacutencubiertosDejalosguisantesenelaguaporlomenos12horasSacalosguisantesdelaguayponlosenenunsarteacutenparacocerAgrega4copasdeaguaporpersonaCubreelsarteacutenymanteacutenloshirvieacutendoseafuegolentopordoshorasAgregalamitaddeunacebollaporpersonaCoacutertalaenpiezasconuncuchilloAgreacutegalasalosguisantesTomaundientedeajoporpersonaCoacutertalosenpiezasconuncuchilloAgreacutegalosalosguisantesTomaunazanahoriaporpersonaCoacutertalasenpiezasiexclConuncuchilloAgreacutegalasalosguisantesCocinapor10

minutosmaacutes`Ylasegundareceta

`Porpersona1tazadeguisantespartidossecosmediacebollapicadaundientedeajoyunazanohoria

Remojalosguisantespor12horasSoakpeasfor12hoursHierveafuegolentopor2horasen

4tazas(porpersona)PicayagregalosvegetalesCocinapor10minutosmaacutes`LasegundaesmaacutescortaymaacutesfaacutecildeinterpretarPeronecesitasentenderunoscuaacutentaspalabrasrelacionadasconlacocina-remojarpicaryimaginovegetal

5FuncionesdeOrderSuperior

90

CuandoprogramamosnopodemosconfiarenquetodaslaspalabrasquenecesitamosesteacutenesperaacutendonoseneldiccionarioAsiacutequepodriacuteascaerenelpatroacutendelaprimerarecetandashtrabajarenlospasosprecisosquelacomputadoradeberealizarunoporunosinverlosconceptosdealtonivelqueestosexpresan

Setienequeconvertirenunasegundanaturalezaparaunprogramadornotarcuandounconceptoestaacuterogandoserabstraiacutedoenunanuevapalabra

Abstrayendotransversaldearray

LasfuuncionesplanascomohemosvistohastaahorasonunabuenaformadeconstruirabstraccionesPeroalgunasvecessequedancortas

Enelcapiacutetuloanterior]estetipodebucleforaparecioacutevariasveces

vararray=[123]for(vari=0iltarraylengthi++)varactual=array[i]consolelog(actual)

EstaacutetratandodedecirCadaelementoescriacutebeloenlaconsolaPerousaunaformarebuscadaqueimplicaunavariableiunarevisioacutendeltamantildeodelarrayyunadeclaracioacutendevariableextraparaguardarelelementoactualApartedecausarunpocodedolordeojosestonosdamuchoespacioparaerrorespotencialesPodriacuteamosaccidentalmentereusarlavariableiescribirmallengthcomolenghtconfundirlasvariablesiyactualyasiacuteporelestiloAsiacutequetratemosdeabstraerestoenunafuncioacuteniquestPuedespensarenalgunaforma

Buenoesfaacutecilescribirunafuncioacutenquevayaatraveacutesdeunarrayyllamarconsolelogencadaelemento

functionlogEach(array)for(vari=0iltarraylengthi++)consolelog(array[i])

PeroiquestqueacutepasasiqueremoshacerotracosaqueloggearloselementosDebidoaquehaceralgopuedeserrepresentadocomounafuncioacutenylasfuncionessonsoacutelovalorespodemospasarnuestraaccioacutencomounvalorfuncioacuten

5FuncionesdeOrderSuperior

91

functionforEach(arrayaccion)for(vari=0iltarraylengthi++)accion(array[i])

forEach([WampeterFomaGranfalloon]consolelog)rarrWampeterrarrFomararrGranfalloon

EnalgunosnavegadoresllamaraconsolelogdeestamaneranofuncionaraPuedesusaralertenlugardeconsolelogsiesteejemplofalla

AmenudonolepasasunafuncioacutenpredefinidaaforEachsinoquecreasunafuncioacutenenelacto

varnumeros=[12345]suma=0forEach(numerosfunction(numero)suma+=numero)consolelog(suma)rarr15

EstolucemuyparecidoalclaacutesicobucleforconsucuerpoescritodebajodeeacutelSinembargoahoraelcuerpoestaacutedentrodelvalorfuncioacutenasiacutecomodentrodelospareacutentesisdelallamadaaforEachEstaeslarazoacutendequetengaqueserterminadoconunallaveyunpareacutentesisdecierre

Usandoestepatroacutenpodemosespecificarunnombredevariableparaelelementoactual(numero)envezdetenerquetomarlodelarraymanuelmente

DehechononecesitamosescribirforEachnosotrosmismosEstaacutedisponiblecomounmeacutetodoestaacutendarenlosarraysDebidoaqueelarrayleespasadocomoelelementosobreelqueactuacuteaelmeacutetodoforEachsoacutelorecibeunargumentorequeridolafuncioacutenqueseraacuteejecutadaparacadaelemento

Parailustrarlouacutetilqueestoesmiremosotravezlafuncioacutendellink04_datahtmlanalysis[capiacutetuloanterior]Contienedosbuclesquerecorrenunarreglo

5FuncionesdeOrderSuperior

92

functionreuneCorrelaciones(diario)varphis=for(varentrada=0entradaltdiariolengthentrada++)vareventos=diario[entrada]eventsfor(vari=0ilteventslengthi++)varevento=eventos[i]if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))returnphis

(((meacutetodoforEach)))forEachlahaceunpocomaacutescortaylimpia

functionreuneCorrelaciones(diario)varphis=diarioforEach(function(entrada)entradaeventosforEach(function(evento)if((eventoinphis))phis[evento]=phi(tableFor(eventodiario))))returnphis

==FuncionesdeOrdenSuperior==

(((funcioacutendeordensuperior)))(((funcioacutencomovalor)))LasfuncionesqueoperanenotrasfunceionesyaseatomaacutendolascomoargumentosoregresaacutendolassonllamadasfuncionesdeordensuperiorSiyahasaceptadoelhechodequelasfuncionessonvaloresreularesnohaynadadeespecialenelhechodequeestasfuncionesexistanElteacuterminosvienedelas((matemaacuteticas))endoacutendeladistincioacutenentrelasfuncionesyotrosvaloresestomadomaacutesseriamente

(((abstraccioacuten)))LasfuncionesdeordensuperiornospermitenabstraeraccionesnosoacutelovaloresPuedenvenirendiferentesformasPorejemplopuedestenerfuncionesquecreennuevasfunciones

functionmayorQue(n)returnfunction(m)returnmgtnvarmayorQue10=mayorQue(10)consolelog(mayorQue10(11))rarrtrue

5FuncionesdeOrderSuperior

93

Ypuedestenerfuncionesquecambienotrasfunciones

functionruidosa(f)returnfunction(arg)consolelog(llamandoconarg)varval=f(arg)consolelog(llamadaconarg-gotval)returnvalruidosa(Boolean)(0)rarrllamandocon0rarrllamadacon0-obtuvefalse

Inclusopuedesescribirfuncionesquecreennuevostipos((controldeflujo))

functiona_menos_que(condicionentonces)if(condicion)entonces()functionrepetir(vecescuerpo)for(vari=0iltvecesi++)cuerpo(i)

repetir(3function(n)a_menos_que(n2function()consolelog(nespar)))rarr0esparrarr2espar

(((innerfunction)))(((nestingoffunctions)))((((block))))(((localvariable)))(((closure)))The((lexicalscoping))rulesthatwediscussedinlink03_functionshtmlscoping[Chapter3]worktoouradvantagewhenusingfunctionsinthiswayInthepreviousexamplethenvariableisa((parameter))totheouterfunctionBecausetheinnerfunctionlivesinsidetheenvironmentoftheouteroneitcanusenThebodiesofsuchinnerfunctionscanaccessthevariablesaroundthemTheycanplayarolesimilartotheblocksusedinregularloopsandconditionalstatementsAnimportantdifferenceisthatvariablesdeclaredinsideinnerfunctionsdonotendupintheenvironmentoftheouterfunctionAndthatisusuallyagoodthing

==Passingalongarguments==

(((functionwrapping)))(((argumentsobject)))Thenoisyfunctiondefinedearlierwhichwrapsitsargumentinanotherfunctionhasaratherseriousdeficit

5FuncionesdeOrderSuperior

94

functionnoisy(f)returnfunction(arg)consolelog(callingwitharg)varval=f(arg)consolelog(calledwitharg-gotval)returnval

Ifftakesmorethanone((parameter))itgetsonlythefirstoneWecouldaddabunchofargumentstotheinnerfunction(arg1arg2andsoon)andpassthemalltofbutitisnotclearhowmanywouldbeenoughThissolutionwouldalsodeprivefoftheinformationinargumentslengthSincewedalwayspassthesamenumberofargumentsitwouldntknowhowmanyargumentswereoriginallygiven

(((applymethod)))(((array-likeobject)))(((functionapplication)))ForthesekindsofsituationsJavaScriptfunctionshaveanapplymethodYoupassitanarray(orarray-likeobject)ofargumentsanditwillcallthefunctionwiththosearguments

functiontransparentWrapping(f)returnfunction()returnfapply(nullarguments)

(((null)))ThatsauselessfunctionbutitshowsthepatternweareinterestedinmdashthefunctionitreturnspassesallofthegivenargumentsandonlythoseargumentstofItdoesthisbypassingitsownargumentsobjecttoapplyThefirstargumenttoapplyforwhichwearepassingnullherecanbeusedtosimulatea((method))callWewillcomebacktothatinthelink06_objecthtmlcall_method[nextchapter]

==JSON==

(((array)))(((functionhigher-order)))(((forEachmethod)))(((dataset)))Higher-orderfunctionsthatsomehowapplyafunctiontotheelementsofanarrayarewidelyusedinJavaScriptTheforEachmethodisthemostprimitivesuchfunctionThereareanumberofothervariantsavailableasmethodsonarraysTofamiliarizeourselveswiththemletsplayaroundwithanotherdataset

(((ancestryexample)))Afewyearsagosomeonecrawledthroughalotofarchivesandputtogetherabookonthehistoryofmyfamilyname(HaverbekemdashmeaningOatbrook)IopenedithopingtofindknightspiratesandalchemistsbutthebookturnsouttobemostlyfullofFlemish((farmer))sFormyamusementIextractedtheinformationonmydirectancestorsandputitintoacomputer-readableformat

5FuncionesdeOrderSuperior

95

(((dataformat)))(((JSON)))ThefileIcreatedlookssomethinglikethis

[sourceapplicationjson]

[nameEmmadeMillianosexfborn1876died1956fatherPetrusdeMillianomotherSophiavanDammenameCarolusHaverbekesexmborn1832died1905fatherCarelHaverbekemotherMariavanBrusselhellipandsoon]

indexseeJavaScriptObjectNotationJSON))ThisformatiscalledJSON(pronouncedldquoJasonrdquo)whichstandsforJavaScriptObjectNotationItiswidelyusedasadatastorageandcommunicationformatontheWeb

(((array)))(((object)))(((quotinginJSON)))(((comment)))JSONissimilartoJavaScriptswayofwritingarraysandobjectswithafewrestrictionsAllpropertynameshavetobesurroundedbydoublequotesandonlysimpledataexpressionsareallowedmdashnofunctioncallsvariablesoranythingthatinvolvesactualcomputationCommentsarenotallowedinJSON

(((JSONstringifyfunction)))(((JSONparsefunction)))(((serialization)))(((deserialization)))(((parsing)))JavaScriptgivesusfunctionsJSONstringifyandJSONparsethatconvertdatafromandtothisformatThefirsttakesaJavaScriptvalueandreturnsaJSON-encodedstringThesecondtakessuchastringandconvertsittothevalueitencodes

varstring=JSONstringify(nameXborn1980)consolelog(string)rarrnameXborn1980consolelog(JSONparse(string)born)rarr1980

(((ANCESTRYFILEdataset)))ThevariableANCESTRY_FILEavailableinthe((sandbox))forthischapterandinhttpeloquentjavascriptnetcodeancestryjs[adownloadablefile]onthewebsite(book(httpeloquentjavascriptnetcode5[_eloquentjavascriptnetcode5]))containsthecontentofmy((JSON))fileasastringLetsdecodeitandseehowmanypeopleitcontains

include_codestrip_log

5FuncionesdeOrderSuperior

96

varancestry=JSONparse(ANCESTRY_FILE)consolelog(ancestrylength)rarr39

==Filteringanarray==

(((arraymethods)))(((arrayfiltering)))(((filtermethod)))(((functionhigher-order)))(((predicatefunction)))Tofindthepeopleintheancestrydatasetwhowereyoungin1924thefollowingfunctionmightbehelpfulItfiltersouttheelementsinanarraythatdontpassatest

functionfilter(arraytest)varpassed=[]for(vari=0iltarraylengthi++)if(test(array[i]))passedpush(array[i])returnpassed

consolelog(filter(ancestryfunction(person)returnpersonborngt1900ampamppersonbornlt1925))rarr[namePhilibertHaverbekehelliphellip]

(((functionasvalue)))(((functionapplication)))ThisusestheargumentnamedtestafunctionvaluetofillinaldquogaprdquointhecomputationThetestfunctioniscalledforeachelementanditsreturnvaluedetermineswhetheranelementisincludedinthereturnedarray

(((ancestryexample)))Threepeopleinthefilewerealiveandyoungin1924mygrandfathergrandmotherandgreat-aunt

(((filtermethod)))(((purefunction)))(((sideeffect)))NotehowthefilterfunctionratherthandeletingelementsfromtheexistingarraybuildsupanewarraywithonlytheelementsthatpassthetestThisfunctionispureItdoesnotmodifythearrayitisgiven

LikeforEachfilterisalsoa((standard))methodonarraysTheexampledefinedthefunctiononlyinordertoshowwhatitdoesinternallyFromnowonwelluseitlikethisinstead

consolelog(ancestryfilter(function(person)returnpersonfather==CarelHaverbeke))rarr[nameCarolusHaverbekehellip]

5FuncionesdeOrderSuperior

97

==Transformingwithmap==

(((arraymethods)))(((mapmethod)))(((ancestryexample)))SaywehaveanarrayofobjectsrepresentingpeopleproducedbyfilteringtheancestryarraysomehowButwewantanarrayofnameswhichiseasiertoread

(((functionhigher-order)))ThemapmethodtransformsanarraybyapplyingafunctiontoallofitselementsandbuildinganewarrayfromthereturnedvaluesThenewarraywillhavethesamelengthastheinputarraybutitscontentwillhavebeenldquomappedrdquotoanewformbythefunction

testjoin

functionmap(arraytransform)varmapped=[]for(vari=0iltarraylengthi++)mappedpush(transform(array[i]))returnmapped

varoverNinety=ancestryfilter(function(person)returnpersondied-personborngt90)consolelog(map(overNinetyfunction(person)returnpersonname))rarr[ClaraAernoudtsEmileHaverbekeMariaHaverbeke]

Interestinglythepeoplewholivedtoatleast90yearsofagearethesamethreepeoplewhowesawbeforemdashthepeoplewhowereyounginthe1920swhichhappenstobethemostrecentgenerationinmydatasetIguess((medicine))hascomealongway

LikeforEachandfiltermapisalsoastandardmethodonarrays

==Summarizingwithreduce==

(((arraymethods)))(((summingexample)))(((reducemethod)))(((ancestryexample)))AnothercommonpatternofcomputationonarraysiscomputingasinglevaluefromthemOurrecurringexamplesummingacollectionofnumbersisaninstanceofthisAnotherexamplewouldbefindingthepersonwiththeearliestyearofbirthinthedataset

(((functionhigher-order)))(((foldfunction)))Thehigher-orderoperationthatrepresentsthispatterniscalledreduce(orsometimesfold)YoucanthinkofitasfoldingupthearrayoneelementatatimeWhensummingnumbersyoudstartwiththenumberzeroandforeachelementcombineitwiththecurrentsumbyaddingthetwo

5FuncionesdeOrderSuperior

98

TheparameterstothereducefunctionareapartfromthearrayacombiningfunctionandastartvalueThisfunctionisalittlelessstraightforwardthanfilterandmapsopaycarefulattention

functionreduce(arraycombinestart)varcurrent=startfor(vari=0iltarraylengthi++)current=combine(currentarray[i])returncurrent

consolelog(reduce([1234]function(ab)returna+b0))rarr10

(((reducemethod)))ThestandardarraymethodreducewhichofcoursecorrespondstothisfunctionhasanaddedconvenienceIfyourarraycontainsatleastoneelementyouareallowedtoleaveoffthestartargumentThemethodwilltakethefirstelementofthearrayasitsstartvalueandstartreducingatthesecondelement

(((ancestryexample)))(((minimum)))Tousereducetofindmymostancientknownancestorwecanwritesomethinglikethis

testno

consolelog(ancestryreduce(function(mincur)if(curbornltminborn)returncurelsereturnmin))rarrnamePauwelsvanHaverbekeborn1535hellip

==Composability==

(((loop)))(((minimum)))(((ancestryexample)))Considerhowwewouldhavewrittenthepreviousexample(findingthepersonwiththeearliestyearofbirth)withouthigher-orderfunctionsThecodeisnotthatmuchworse

testno

5FuncionesdeOrderSuperior

99

varmin=ancestry[0]for(vari=1iltancestrylengthi++)varcur=ancestry[i]if(curbornltminborn)min=curconsolelog(min)rarrnamePauwelsvanHaverbekeborn1535hellip

Thereareafewmore((variable))sandtheprogramistwolineslongerbutstillquiteeasytounderstand

[[averagefunction]](((averagefunction)))(((composability)))(((functionhigher-order)))Higher-orderfunctionsstarttoshinewhenyouneedto_composefunctionsAsanexampleletswritecodethatfindstheaverageageformenandforwomeninthedataset

testclip

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylengthfunctionage(p)returnpdied-pbornfunctionmale(p)returnpsex==mfunctionfemale(p)returnpsex==f

consolelog(average(ancestryfilter(male)map(age)))rarr6167consolelog(average(ancestryfilter(female)map(age)))rarr5456

(((plusfunction)))(((+operator)))(((functionasvalue)))(ItsabitsillythatwehavetodefineplusasafunctionbutoperatorsinJavaScriptunlikefunctionsarenotvaluessoyoucantpassthemasarguments)

(((abstraction)))(((vocabulary)))Insteadoftanglingthelogicintoabig((loop))itisneatlycomposedintotheconceptsweareinterestedinmdashdeterminingsexcomputingageandaveragingnumbersWecanapplytheseonebyonetogettheresultwearelookingfor

ThisisfabulousforwritingclearcodeUnfortunatelythisclaritycomesatacost

==Thecost==

(((efficiency)))(((optimization)))Inthehappylandofelegantcodeandprettyrainbowstherelivesaspoil-sportmonstercalledinefficiency

5FuncionesdeOrderSuperior

100

(((elegance)))(((arraycreation)))(((purefunction)))(((composability)))AprogramthatprocessesanarrayismostelegantlyexpressedasasequenceofcleanlyseparatedstepsthateachdosomethingwiththearrayandproduceanewarrayButbuildingupallthoseintermediatearraysissomewhatexpensive

(((readability)))(((functionapplication)))(((forEachmethod)))(((functionasvalue)))LikewisepassingafunctiontoforEachandlettingthatmethodhandlethearrayiterationforusisconvenientandeasytoreadButfunctioncallsinJavaScriptarecostlycomparedtosimpleloopbodies

(((abstraction)))AndsoitgoeswithalotoftechniquesthathelpimprovetheclarityofaprogramAbstractionsaddlayersbetweentherawthingsthecomputerisdoingandtheconceptsweareworkingwithandthuscausethemachinetoperformmoreworkThisisnotanironlawmdashthereareprogramminglanguagesthathavebettersupportforbuildingabstractionswithoutaddinginefficienciesandeveninJavaScriptanexperiencedprogrammercanfindwaystowriteabstractcodethatisstillfastButitisaproblemthatcomesupalot

(((profiling)))FortunatelymostcomputersareinsanelyfastIfyouareprocessingamodestsetofdataordoingsomethingthathastohappenonlyonahumantimescale(sayeverytimetheuserclicksabutton)thenitdoesnotmatterwhetheryouwroteaprettysolutionthattakeshalfamillisecondorasuper-optimizedsolutionthattakesatenthofamillisecond

(((nestingofloops)))(((innerloop)))(((complexity)))ItishelpfultoroughlykeeptrackofhowoftenapieceofyourprogramisgoingtorunIfyouhavea((loop))insidealoop(eitherdirectlyorthroughtheouterloopcallingafunctionthatendsupperformingtheinnerloop)thecodeinsidetheinnerloopwillenduprunningNtimesMtimeswhereNisthenumberoftimestheouterlooprepeatsandMisthenumberoftimestheinnerlooprepeatswithineachiterationoftheouterloopIfthatinnerloopcontainsanotherloopthatmakesProundsitsbodywillrunMtimesNtimesPtimesandsoonThiscanadduptolargenumbersandwhenaprogramisslowtheproblemcanoftenbetracedtoonlyasmallpartofthecodewhichsitsinsideaninnerloop

==Great-great-great-great-==

(((ancestryexample)))My((grandfather))PhilibertHaverbekeisincludedinthedatafileBystartingwithhimIcantracemylineagetofindoutwhetherthemostancientpersoninthedataPauwelsvanHaverbekeismydirectancestorAndifheisIwouldliketoknowhowmuch((DNA))Itheoreticallysharewithhim

(((byNameobject)))(((map)))(((datastructure)))(((objectasmap)))Tobeabletogofromaparentsnametotheactualobjectthatrepresentsthispersonwefirstbuildupanobjectthatassociatesnameswithpeople

5FuncionesdeOrderSuperior

101

include_codestrip_log

varbyName=ancestryforEach(function(person)byName[personname]=person)

consolelog(byName[PhilibertHaverbeke])rarrnamePhilibertHaverbekehellip

NowtheproblemisnotentirelyassimpleasfollowingthefatherpropertiesandcountinghowmanyweneedtoreachPauwelsThereareseveralcasesinthefamily((tree))wherepeoplemarriedtheirsecondcousins(tinyvillagesandallthat)ThiscausesthebranchesofthefamilytreetorejoininafewplaceswhichmeansIsharemorethan12^G^ofmygeneswiththispersonwhereGforthenumberofgenerationsbetweenPauwelsandmeThisformulacomesfromtheideathateachgenerationsplitsthegenepoolintwo

(((reducemethod)))(((datastructure)))AreasonablewaytothinkaboutthisproblemistolookatitasbeinganalogoustoreducewhichcondensesanarraytoasinglevaluebyrepeatedlycombiningvalueslefttorightInthiscasewealsowanttocondenseourdatastructuretoasinglevaluebutinawaythatfollowsfamilylinesTheshapeofthedataisthatofafamilytreeratherthanaflatlist

ThewaywewanttoreducethisshapeisbycomputingavalueforagivenpersonbycombiningvaluesfromtheirancestorsThiscanbedonerecursivelyifweareinterestedinpersonAwehavetocomputethevaluesforArsquosparentswhichinturnrequiresustocomputethevalueforArsquosgrandparentsandsoonInprinciplethatdrequireustolookataninfinitenumberofpeoplebutsinceourdatasetisfinitewehavetostopsomewhereWellallowa((defaultvalue))tobegiventoourreductionfunctionwhichwillbeusedforpeoplewhoarenotinthedataInourcasethatvalueissimplyzeroontheassumptionthatpeoplenotinthelistdontshareDNAwiththeancestorwearelookingat

(((recursion)))(((reduceAncestorsfunction)))GivenapersonafunctiontocombinevaluesfromthetwoparentsofagivenpersonandadefaultvaluereduceAncestorscondensesavaluefromafamilytree

include_code

5FuncionesdeOrderSuperior

102

functionreduceAncestors(personfdefaultValue)functionvalueFor(person)if(person==null)returndefaultValueelsereturnf(personvalueFor(byName[personmother])valueFor(byName[personfather]))returnvalueFor(person)

(((functionhigher-order)))Theinnerfunction(valueFor)handlesasinglepersonThroughthe((magic))ofrecursionitcansimplycallitselftohandlethefatherandthemotherofthispersonTheresultsalongwiththepersonobjectitselfarepassedtofwhichreturnstheactualvalueforthisperson

Wecanthenusethistocomputetheamountof((DNA))my((grandfather))sharedwithPauwelsvanHaverbekeanddividethatbyfour

start_codebottom_lines2testclipinclude_codetop_lines6

functionsharedDNA(personfromMotherfromFather)if(personname==PauwelsvanHaverbeke)return1elsereturn(fromMother+fromFather)2varph=byName[PhilibertHaverbeke]consolelog(reduceAncestors(phsharedDNA0)4)rarr000049

ThepersonwiththenamePauwelsvanHaverbekeobviouslyshared100percentofhisDNAwithPauwelsvanHaverbeke(therearenopeoplewhosharenamesinthedataset)sothefunctionreturns1forhimAllotherpeoplesharetheaverageoftheamountsthattheirparentsshare

SostatisticallyspeakingIshareabout005percentofmy((DNA))withthis16th-centurypersonItshouldbenotedthatthisisonlyastatisticalapproximationnotanexactamountItisarathersmallnumberbutgivenhowmuchgeneticmaterialwecarry(about3billionbasepairs)theresstillprobablysomeaspectinthebiologicalmachinethatismethatoriginateswithPauwels

(((ancestryexample)))(((reduceAncestorsfunction)))(((abstraction)))WecouldalsohavecomputedthisnumberwithoutrelyingonreduceAncestorsButseparatingthegeneralapproach(condensingafamilytree)fromthespecificcase(computingsharedDNA)can

5FuncionesdeOrderSuperior

103

improvetheclarityofthecodeandallowsustoreusetheabstractpartoftheprogramforothercasesForexamplethefollowingcodefindsthepercentageofapersonsknownancestorswholivedpast70(bylineagesopeoplemaybecountedmultipletimes)

testclip

functioncountAncestors(persontest)functioncombine(currentfromMotherfromFather)varthisOneCounts=current=personampamptest(current)returnfromMother+fromFather+(thisOneCounts10)returnreduceAncestors(personcombine0)functionlongLivingPercentage(person)varall=countAncestors(personfunction(person)returntrue)varlongLiving=countAncestors(personfunction(person)return(persondied-personborn)gt=70)returnlongLivingallconsolelog(longLivingPercentage(byName[EmileHaverbeke]))rarr0129

SuchnumbersarenottobetakentooseriouslygiventhatourdatasetcontainsaratherarbitrarycollectionofpeopleButthecodeillustratesthefactthatreduceAncestorsgivesusausefulpieceof((vocabulary))forworkingwiththefamilytreedatastructure

==Binding==

(((bindmethod)))(((partialapplication)))(((functionapplication)))Thebindmethodwhichallfunctionshavecreatesanewfunctionthatwillcalltheoriginalfunctionbutwithsomeoftheargumentsalreadyfixed

(((filtermethod)))(((functionasvalue)))ThefollowingcodeshowsanexampleofbindinuseItdefinesafunctionisInSetthattellsuswhetherapersonisinagivensetofstringsTocallfilterinordertocollectthosepersonobjectswhosenamesareinaspecificsetwecaneitherwriteafunctionexpressionthatmakesacalltoisInSetwithoursetasitsfirstargumentorpartiallyapplytheisInSetfunction

5FuncionesdeOrderSuperior

104

vartheSet=[CarelHaverbekeMariavanBrusselDonaldDuck]functionisInSet(setperson)returnsetindexOf(personname)gt-1

consolelog(ancestryfilter(function(person)returnisInSet(theSetperson)))rarr[nameMariavanBrusselhellipnameCarelHaverbekehellip]consolelog(ancestryfilter(isInSetbind(nulltheSet)))rarrhellipsameresult

ThecalltobindreturnsafunctionthatwillcallisInSetwiththeSetasfirstargumentfollowedbyanyremainingargumentsgiventotheboundfunction

(((null)))Thefirstargumentwheretheexamplepassesnullisusedfor((methodcall))ssimilartothefirstargumenttoapplyIlldescribethisinmoredetailinthelink06_objecthtmlcall_method[nextchapter]

==Summary==

BeingabletopassfunctionvaluestootherfunctionsisnotjustagimmickbutadeeplyusefulaspectofJavaScriptItallowsustowritecomputationswithldquogapsrdquointhemasfunctionsandhavethecodethatcallsthesefunctionsfillinthosegapsbyprovidingfunctionvaluesthatdescribethemissingcomputations

Arraysprovideanumberofusefulhigher-ordermethodsmdashforEachtodosomethingwitheachelementinanarrayfiltertobuildanewarraywithsomeelementsfilteredoutmaptobuildanewarraywhereeachelementhasbeenputthroughafunctionandreducetocombineallanarrayselementsintoasinglevalue

FunctionshaveanapplymethodthatcanbeusedtocallthemwithanarrayspecifyingtheirargumentsTheyalsohaveabindmethodwhichisusedtocreateapartiallyappliedversionofthefunction

==Exercises==

===Flattening===

(((flattening(exercise))))(((reducemethod)))(((concatmethod)))(((array)))Usethereducemethodincombinationwiththeconcatmethodtoldquoflattenrdquoanarrayofarraysintoasinglearraythathasalltheelementsoftheinputarrays

ifdefinteractive_target[]

5FuncionesdeOrderSuperior

105

testno

vararrays=[[123][45][6]]Yourcodehererarr[123456]

endifinteractive_target[]

===Mother-childagedifference===

(((ancestryexample)))(((agedifference(exercise))))(((averagefunction)))Usingtheexampledatasetfromthischaptercomputetheaverageagedifferencebetweenmothersandchildren(theageofthemotherwhenthechildisborn)Youcanusetheaveragefunctiondefinedlink05_higher_orderhtmlaverage_function[earlier]inthischapter

(((byNameobject)))NotethatnotallthemothersmentionedinthedataarethemselvespresentinthearrayThebyNameobjectwhichmakesiteasytofindapersonsobjectfromtheirnamemightbeusefulhere

ifdefinteractive_target[]

testnoinclude_code

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

varbyName=ancestryforEach(function(person)byName[personname]=person)

Yourcodehere

rarr312

endifinteractive_target[]

hint

(((agedifference(exercise))))(((filtermethod)))(((mapmethod)))(((null)))(((averagefunction)))Becausenotallelementsintheancestryarrayproduceusefuldata(wecantcomputetheagedifferenceunlessweknowthebirthdateofthemother)wewillhavetoapplyfilterinsomemannerbeforecallingaverageYoucoulddoitasafirstpassbydefiningahasKnownMotherfunctionandfilteringonthatfirstAlternativelyyoucouldstartby

5FuncionesdeOrderSuperior

106

callingmapandinyourmappingfunctionreturneithertheagedifferenceornullifnomotherisknownThenyoucancallfiltertoremovethenullelementsbeforepassingthearraytoaverage

hint

===Historicallifeexpectancy===

(((lifeexpectancy(exercise))))Whenwelookedupallthepeopleinourdatasetthatlivedmorethan90yearsonlythelatestgenerationinthedatacameoutLetstakeacloserlookatthatphenomenon

(((averagefunction)))ComputeandoutputtheaverageageofthepeopleintheancestrydatasetpercenturyApersonisassignedtoa((century))bytakingtheiryearofdeathdividingitby100androundingitupasinMathceil(persondied100)

ifdefinteractive_target[]

testno

functionaverage(array)functionplus(ab)returna+breturnarrayreduce(plus)arraylength

Yourcodehere

rarr16435175121852819548208472194

endifinteractive_target[]

hint

(((lifeexpectancy(exercise))))Theessenceofthisexampleliesin((grouping))theelementsofacollectionbysomeaspectoftheirsmdashsplittingthearrayofancestorsintosmallerarrayswiththeancestorsforeachcentury

(((array)))(((map)))(((objectasmap)))Duringthegroupingprocesskeepanobjectthatassociates((century))names(numbers)witharraysofeitherpersonobjectsoragesSincewedonotknowinadvancewhatcategorieswewillfindwellhavetocreatethemonthefly

5FuncionesdeOrderSuperior

107

ForeachpersonaftercomputingtheircenturywetestwhetherthatcenturywasalreadyknownIfnotaddanarrayforitThenaddtheperson(orage)tothearrayforthepropercentury

(((forinloop)))(((averagefunction)))Finallyaforinloopcanbeusedtoprinttheaverageagesfortheindividualcenturies

hint

(((grouping)))(((map)))(((objectasmap)))(((groupByfunction)))ForbonuspointswriteafunctiongroupBythatabstractsthegroupingoperationItshouldacceptasargumentsanarrayandafunctionthatcomputesthegroupforanelementinthearrayandreturnsanobjectthatmapsgroupnamestoarraysofgroupmembers

===Everyandthensome===

(((predicatefunction)))(((everyandsome(exercise))))(((everymethod)))(((somemethod)))(((arraymethods)))(((ampampoperator)))(((||operator)))ArraysalsocomewiththestandardmethodseveryandsomeBothtakeapredicatefunctionthatwhencalledwithanarrayelementasargumentreturnstrueorfalseJustlikeampampreturnsatruevalueonlywhentheexpressionsonbothsidesaretrueeveryreturnstrueonlywhenthepredicatereturnstrueforallelementsofthearraySimilarlysomereturnstrueassoonasthepredicatereturnstrueforanyoftheelementsTheydonotprocessmoreelementsthannecessarymdashforexampleifsomefindsthatthepredicateholdsforthefirstelementofthearrayitwillnotlookatthevaluesafterthat

Writetwofunctionseveryandsomethatbehavelikethesemethodsexceptthattheytakethearrayastheirfirstargumentratherthanbeingamethod

ifdefinteractive_target[]

testno

Yourcodehere

consolelog(every([NaNNaNNaN]isNaN))rarrtrueconsolelog(every([NaNNaN4]isNaN))rarrfalseconsolelog(some([NaN34]isNaN))rarrtrueconsolelog(some([234]isNaN))rarrfalse

endifinteractive_target[]

hint

5FuncionesdeOrderSuperior

108

(((everyandsome(exercise))))(((short-circuitevaluation)))(((returnkeyword)))Thefunctionscanfollowasimilarpatterntothelink05_higher_orderhtmlforEach[definition]offorEachatthestartofthechapterexceptthattheymustreturnimmediately(withtherightvalue)whenthepredicatefunctionreturnsfalsemdashortrueDontforgettoputanotherreturnstatementaftertheloopsothatthefunctionalsoreturnsthecorrectvaluewhenitreachestheendofthearray

hint

5FuncionesdeOrderSuperior

109

LaVidaSecretadelosObjetosElproblemaconloslenguajesorientadosaobjetosesquetienentodosunmedioimpliacutecitoquellevanconsigoTuquieresunplaacutetanoperoeresungorilaconunplaacutetanoylajunglaenteraJoeArmstrongentrevistadoenCodersatWork

Cuandounprogramadordice˝objeto˝esteesunteacuterminoamplioEnmiprofesioacutenlosobjetossonunaformadevidatemadeguerrassagradasyunaamadapalabrallamativaquetodaviacuteanohaperdidosugranpoder

ParaalguienajenoestoesprobablementeunpococonfusoEmpecemosconunaintroduccioacutenalahistoriadelosobjetoscomounaformadeprogramacioacuten

Historia

EstahistoriacomolamayorpartedelashistoriasdeprogramacioacutencomienzaconelproblemadelacomplejidadUnafilosofiacuteaesquelacomplejidadpuedesermanejableseparaacutendolaenpequentildeaspartesquesonaisladasunasdeotrasEstasparteshanterminadoconelnombredeobjetos

Unobjetoesunacaacutepsulaopacaqueocultaunasofisticadacomplejidadensuinterioryensulugarnosofreceunospocosreguladoresyconectores(comoporejemplomeacutetodo_s)quepresentanuna_interfazatraveacutesdelacualelobjetoesusadoLaideaesquelalainterfazesrelativamentesimpleytodaslascosascomplejasquevandentrodelobjetopuedenserignoradascuandotrabajamosconel

6LaVidaSecretaDeLosObjetos

110

ComoejemplopuedesimaginarteunobjetoquetedeacuteunainterfazparaunaacutereadelapantallaTedaunaformadedibujarformasotextoenestaaacutereaperoocultalosdetallesdecomoesasformassonconvertidasalospixelesquedecoranlapantallaactualmetePuedestenerunconjuntodemeacutetodos-porejemplodibujarCirculo-yestossonlouacutenicoquenecesitasparausarunobjeto

Estasideasfueronpuestasenmarchaenlos70los80ylos90fueronacompantildeadasporungranbombo-larevolucioacutendelaprogramacioacutenorientadaaobjetosInmediatamentehabiacuteaungrupodegentedeclarandoquelosobjetoseranelcaminocorrectoalaprogramacioacuten-yquenoincluirobjetoseraunsinsentidoestabaobsoleto

EstetipodefanatismosiempreproducemuchaestupideznopraacutecticayhahabidounapequentildeacontrarevolucioacutendespueacutesdeestoActualmenteenalgunosciacuterculoslosobjetostienenunareputacioacutenbastantemala

YoprefieroabordareltemadesdelapraacutecticaenlugardedesdelaideologiacuteaHayvariosconceptosuacutetilesmaacutesimportantesquelaencapsulacioacuten(distinguirentrelacomplejidadinternayexternadelainterfaz)quelaculturadelaprogramacioacutenorientadaaobjetosa

6LaVidaSecretaDeLosObjetos

111

popularizadoEstossondignosdeestudio

EnestecapiacutetulosedescribendeformaexceacutentricalosobjetosylasteacutecnicasclaacutesicassobrecomoserelacionanentresiacutelosobjetosenJavaScript

Meacutetodos

LosmeacutetodossonpropiedadessimplesquecontienenfuncionescomovaloresEsteesunmeacutetodosimple

varconejo=conejohablar=function(linea)consolelog(Elconejodice+linea+)

conejohablar(Estoyvivo)rarrElconejodiceEstoyvivo

NormalmenteelmeacutetodonecesitahaceralgoconelobjetodesdeelqueselehallamadoCuandounafuncioacutenesllamadacomomeacutetodo-sebuscacomopropiedadyesinmediatamentellamadacomoenobjetometodo()mdashlavariableespecialthisestaensucuerpoyapuntaraacutealobjetoquelahallamado

functionhablar(linea)consolelog(Elconejo+thistipo+dice+line+)varconejoBlanco=tipoblancohablarhablarvarconejoGordo=tipogordohablarhablar

conejoBlancohablar(iexclPormisorejasylospelosdemi+bigotequetardeseestaacutehaciendo)rarrElconejoblancodiceiexclPormisorejasylospelosdemibigotequetardeseestaacutehaciendoconejoGordohablar(Puedesestarsegurodequemecomeriacutea+unazanahoria)rarrElconejogordodicePuedesestarsegurodequemecomeriacuteaunazanahoria

ElcoacutedigousalapalabraclavethisparalasalidadeltipodeconejoqueestaacutehablandoSepuederellamarconlosmeacutetodosapplyybindambostomanunprimerargumentoquepuedeserutilizadoparasimularllamadasalmeacutetodoElprimerargumentoesdeechoutilizadoparadarvalorathis

6LaVidaSecretaDeLosObjetos

112

HayunmeacutetodosimilaraapplyllamadocallEstellamaalafuncioacutenqueesunmeacutetodoperotomasusargumentosnormalmenteenlugardeconunarrayComoapplyybindcallpuedepasarunvalorespeciacuteficodethis

hablarapply(conejoGordo[iexclBurp])rarrElconejogordodiceiexclBurphablarcall(tipoviejoiexclOhiexclAh)rarrElconejoviejodiceiexclOhiexclAh

Prototipos

(Fiacutejatedetenidamente)

varvacio=consolelog(vaciotoString)rarrfunctiontoString()hellipconsolelog(vaciotoString())rarr[objectObject]

AcabodeextraerunapropiedaddeunobjetovaciacuteoiexclMagia

BiennorealmenteSimplementeheomitidoinformacioacutenacercadecomolosObjetosfuncionanenJavaScriptAdemaacutesdesuspropiedadescasitodoslosobjetosademaacutestienenunprototipoUnprototipoesotroobjetoqueesusadocomoalternativafuentedepropiedadesCuandounobjetotieneunallamadaaunapropiedadquenoposeesebuscaraacuteensuprototipodespueacutesenelprototipodesuprototipoyasiacutesucesivamente

EntoncesiquestCualeselprototipodeesteobjetovaciacuteoEselgenialprototipoancestrallaentidaddetraacutesdecasitodoslosobjetosObjectprototype

consolelog(ObjectgetPrototypeOf()==Objectprototype)rarrtrueconsolelog(ObjectgetPrototypeOf(Objectprototype))rarrnull

ComoimaginaraacuteslafuncioacutenObjectgetPrototypeOfdevuelveelprototipodeunobjeto

LasrelacionesdeprototipoenJavaScripttienenformadeaacuterbolylaraiacutezdeestaestructuraesObjectprototypeEsteproveeunospocosmeacutetodosquesemostraraacutenencasitodoslosobjetoscomotoStringqueconvierteunobjetoenunarepresentacioacutenenunacadenadetexto

6LaVidaSecretaDeLosObjetos

113

MuchosobjetosnotienendirectamenteObjectprototypecomosuprototipoperoensulugartienenotroobjetoquelesproveesuspropiedadespordefectoLasfuncionesderivandeFunctionprototypeylosarraysderivandeArrayprototype

consolelog(ObjectgetPrototypeOf(isNaN)==Functionprototype)rarrtrueconsolelog(ObjectgetPrototypeOf([])==Arrayprototype)rarrtrue

ComounobjetoprototipotienesupropioprototiponormalmenteObjectprototypeentoncesesteindirectamenteproveedemeacutetodoscomotoString

LafuncioacutenObjectgetPrototypeOfobviamentedevuelveelprototipodeunobjetoPuedesusarObjectcreateparacrearunobjetoconunprototipoespeciacutefico

varprotoConejo=hablarfunction(linea)consolelog(Elconejo+thistype+dice+linea+)varconejoAsesino=Objectcreate(protoConejo)conejoAsesinotype=asesinoconejoAsesinohablar(SKREEEE)rarrElconejoasesinodiceSKREEEE

ElldquoprotordquoconejoactuacuteacomocontainerparalaspropiedadesquesoncompartidasportodoslosconejosUnobjetoconejoindividualcomoelconejoasesinocontienepropiedadesqueseaplicanuacutenicamenteasiacutemismoenestecasosutipoypropiedadesderivadasdesuprototipo

Constructores

UnaformamaacutesconvenientedecrearobjetosquederivensuformadeprototiposcompartidosesusarunconstructorEnJavaScriptllamaraunafuncioacutenconlapalabraclavenewdelantedeellahacequeseatratadacomounconstructorElconstructortendraacutesuvariablethisenlosliacutemitesdelobjetocreadoysinoseespeciacuteficaotrovalordeobjetoesteseraacuteelnuevoobjetoqueretornelallamada

Unobjetocreadoconnewsedicequeesunainstanciadesuconstructor

6LaVidaSecretaDeLosObjetos

114

TenemosunconstructorsimpleparalosconejosEsunaconvencioacutencapitalizar(ponerlaprimeraletraenmayuacutescula)losnombresdelosconstructoresasiacutesonfaacutecilmentedistinguidosdeotrasfunciones

functionConejo(tipo)thistipo=tipo

varconejoAsesino=newConejo(asesino)varconejoNegro=newConejo(negro)consolelog(conejoNegrotipo)rarrnegro

Losconstructores(dehechotodaslasfunciones)automaacuteticamentetienenunapropiedadllamadaprototypequepordefectocontieneunobjetoplanovaciacuteoquederivadeObjectprototypeTodaslasinstanciascreadasconesteconstructortendraacutenesteobjetocomosu((prototipo))AsiacutequeparaantildeadirunmeacutetodohablaralosconejoscreadosconelconstructorConejosimplementehacemoslosiguiente

Conejoprototypehablar=function(linea)consolelog(Elconejo+thistipo+dice+linea+)conejoNegrohablar(Maldicioacuten)rarrElconejonegrodiceMaldicioacuten

Esimportantenotarladiferenciaentrelaformaenqueunprototipoesasociadoconunconstructor(atraveacutesdesupropiedadprototype)ylaformaenlaquelosobjetostienenunprototipo(quepodemosconsultarconObjectgetPrototypeOf)ElprototipoactualdeunconstructoresFunctionprototypedesdequelosconstructoressonfuncionesEstapropiedadprototypeseraacuteelprototipodelasinstanciascreadasatraveacutesdeelperonosupropioprototipo

SobreEscribiendoLasPropiedadesDerivadas

CuandoantildeadesunapropiedadaunobjetoesteacutepresenteenelprototipoonolapropiedadesantildeadidaaeseobjetoquedeahoraenadelantetendraacutecomosupropiedadSiexisteunapropiedadconelmismonombreenelprototipoestapropiedadnoafectaraacutemaacutesalobjetoElprototipoporsimismonocambia

6LaVidaSecretaDeLosObjetos

115

Conejoprototypedentadura=pequentildeaconsolelog(conejoNegrodentadura)rarrpequentildeaconejoAsensinodentadura=largaafiladaysangrientaconsolelog(conejoAsesinodentadura)rarrlargaafiladaysangrientaconsolelog(conejoNegrodentadura)rarrpequentildeaconsolelog(Conejoprototypedentadura)rarrpequentildea

ElsiguientediagramarepresentalasituacioacutendespueacutesdeejecutarestecoacutedigoElConejoyObjeto_prototipo_sestaacutendetraacutesdeconejoAsesinocomounaespecieteloacutendefondodondesuspropiedadesquenosonencontradasenelobjetoporsimismopuedenserbuscadas

SobreescribirpropiedadesqueexistenenunprototipoesamenudoalgouacutetilquehacerComomuestraelejemplodeladentaduradelconejoestopuedeserusadoparaexpresarpropiedadesexcepcionaleseninstanciasdeunaclasemaacutesgeneacutericadeobjetosmientrasdejamoslosobjetosnoexcepcionalessimplementetomarunvalorestaacutendardesuprototipo

EstoesademaacutesusadoparadaralosprototiposdefuncioacutenyarrayunmeacutetodotoStringdiferentedelbaacutesicoprototipodelosobjetos

consolelog(ArrayprototypetoString==ObjectprototypetoString)rarrfalseconsolelog([12]toString())rarr12

LlamaratoStringenunarraydaunresultadosimilarajoin()-estoponecomasentrelosvaloresdelarrayUnallamadadirectaaObjectprototypetoStringconunarrayproduceunacadenadetextodiferenteEstafuncioacutennosabeacercadearraysasiacuteque

6LaVidaSecretaDeLosObjetos

116

simplementeponelapalabraobjectyelnombredeltipoentrecorchetes

consolelog(ObjectprototypetoStringcall([12]))rarr[objectArray]

Interferenciadeprototipos

UnprototipopuedeserusadoencualquiermomentoparaantildeadirnuevaspropiedadesymeacutetodosatodoslosobjetosbasadoseneacutelPorejemplopuedesernecesarioparaponeranuestrosconejosabailar

Conejoprototypebailar=function()consolelog(Elconejo+thistype+bailaunpaso)conejoAsesinobailar()rarrElconejoasesinobailaunpaso

EstoesconvenientePerohaysituacionesdondeestocausaproblemasEncapiacutetulosanterioreshemosusadounobjetocomoformadeasociarvaloresconnombrescreandopropiedadesparalosnombresydaacutendolesloscorrespondientesvalorescomosuvalorAquiacutehayunejemploCapitulo4

varmapa=functionguardarPhi(eventophi)mapa[evento]=phi

guardarPhi(pizza0069)guardarPhi(aacuterboltocado-0081)

PodemositerarsobretodoslosvaloresdephienelobjetousandounbucleforinycomprobarcuandounnombreestausandoeloperadorregularinPerodesafortunadamenteelobjetodelprototipocontinuaconsucamino

6LaVidaSecretaDeLosObjetos

117

ObjectprototypesinSentido=holafor(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadorarrsinSentidoconsolelog(sinSentidoinmapa)rarrtrueconsolelog(toStringinmapa)rarrtrue

BorrarlapropiedadproblemaacuteticadeleteObjectprototypesinSentido

EstatodomalNohayeventollamadosinSentidoennuestrosetdedatosYdefinitivamentenohayeventollamadotoString

ExtrantildeamentetoStringnosemuestraenelbucleforinperoeloperadorinharetornadotrueparaelEstoesporqueJavaScriptdistingueentrepropiedadesenumerable(enumerables)ynonenumerable(noenumerables)

TodaslaspropiedadesquecreamossimplementeasignaacutendolassonenumerablesLaspropiedadesestaacutendarenObjectprototypesontodasnonenumerablequeesporloquenosemuestranenunbuclecomounforin

EsposibledefinirnuestraspropiaspropiedadesnonenumberableusandolafuncioacutenObjectdefinePropertyestanospermitecontrolareltipodepropiedadqueestamoscreando

ObjectdefineProperty(ObjectprototypeocultarSinSentidoenumerablefalsevaluehola)for(varnombreinmapa)consolelog(nombre)rarrpizzararraacuterboltocadoconsolelog(mapaocultarSinSentido)rarrhola

EntoncesahoralapropiedadestaperonosemuestraenunbucleEstoesbuenoPeroseguimosteniendoelproblemaconeloperadorregularindemandandoquelaspropiedadesdelObjectprototypeexistenennuestroobjetoParaestopodemosusarelmeacutetododeobjetohasOwnProperty

consolelog(mapahasOwnProperty(toString))rarrfalse

6LaVidaSecretaDeLosObjetos

118

EstemeacutetodonosdicecuandoelobjetoporsimismotienelapropiedadsinmirarensusprototiposEstoesamenudounainformacioacutenmaacutesuacutetilquelaquenosdaeloperadorin

Cuandotuestaacutespreocupadodequealgo(alguacutenotrocoacutedigoquehasincluidoentuprograma)puedetenerproblemasconelobjetobaseprototipoterecomiendoescribirbuclesforincomoeste

for(varnombreinmapa)if(mapahasOwnProperty(nombre))estaesunapropiedadpropia

Objetossinprototipo

PeroelagujerodelconejonoacabaaquiacuteiquestQueacutepasasialguienregistraelnombrehasOwnPropertyennuestroobjetomapayleasignaelvalor42AhoralallamadaamapahasOwnPropertyintentaraacutellamaralapropiedadlocalquecontieneunnuacutemeronounafuncioacuten

EnestecasolosprototipossolocontinuacuteansucaminoynosotrospodemospreferirtenerobjetossinprototiposporahoraVemoslafuncioacutenObjectcreatequenospermitecrearunobjetoconunprototipoespeciacuteficoLepuedespasarnullcomoprototipoparacrearunobjetovaciacuteosinprototipoParaobjetoscomomapdondelaspropiedadespuedensercualquieraestoesexactamenteloquequeremos

varmapa=Objectcreate(null)mapa[pizza]=0069consolelog(toStringinmapa)rarrfalseconsolelog(pizzainmapa)rarrtrue

iexclMuchomejorYanonecesitaremoslachapuzadehasOwnPropertyporquetodaslaspropiedadesqueelobjetotienesonsuspropiaspropiedadesAhorapodemosusardeformasegurabuclesforinnohayproblemaconloquelagentelehayaestadohaciendoaObjectprototype

Polimorfismo

CuandollamasalafuncioacutenStringqueconvierteunvalorenunacadenaenunobjetoestallamaraacutealmeacutetodotoStringcuandoelobjetotratedecrearunacadenaconsentidopararetornarlaHemencionadoquealgunodelosprototiposestaacutendardefinensupropia

6LaVidaSecretaDeLosObjetos

119

versioacutendetoStringasiacutequeellospuedencrearcadenasquecontenganinformacioacutenmaacutesuacutetilque[objectObject]

EstaesunasimpleinstanciadeunapoderosaideaCuandountrozodecoacutedigoesescritoparatrabajarconobjetosquetienenunainterfazconcreta-enestecasounmeacutetodotoString-entoncescualquiertipodeobjetoquesoporteestainterfazypuedaserintroducidoenelcoacutedigosimplementefuncionaraacute

Estateacutecnicaesllamadapolimorfismo-aunquenohaycambiodeformarealactualmenteinvolucradoElcoacutedigopolimoacuterficopuedetrabajarconvaloresdediferentesformastantascomoseansoportadasporlainterfaz

Dandoestiloaunatabla

VoyatrabajaratraveacutesdeunejemplounpocomaacutescomplicadoenunintentodedarteunaideamejordecomoseutilizaelpolimorfismoylaprogramacioacutenorientadaaobjetosengeneralElproyectoesesteescribiremosunprogramaquedadounarraydearraysdetablaceldasconstruyaunacadenadetextoquecontengaungenialdisentildeodetabla-significaquelascolumnasylasfilasestaacutencorrectamentealineadasAlgocomoesto

nombrealturapaiacutes-------------------------------Kilimanjaro5895TanzaniaEverest8848NepalMountFuji3776JapanMontBlanc4808ItalyFranceVaalserberg323NetherlandsDenali6168UnitedStatesPopocatepetl5465Mexico

LaformaenquenuestrosistemadegeneracioacutendetablasfuncionaraacuteesquelafuncioacutengeneradorapreguntaraacuteacadaceldacualvaasersuanchoyaltoydespueacutesusaresainformacioacutenparadeterminarlaanchuradelascolumnasylaalturadelasfilasLafuncioacutengeneradoradespueacutespediraacutealasceldasquesedibujenasiacutemismasconeltamantildeocorrectoyensamblandolosresultadosenunasolacadena

ElprogramadeestilosecomunicaraacuteconlosobjetosceldaatraveacutesdeunainterfazbiendefinidaDeestaformalostiposdeceldaqueelprogramasoportanoestaraacutenfijadosPodremosantildeadirnuevostiposdeceldamaacutesadelante-porejemploceldassubrayadasparalacabeceradelatabla-ysilosoportanuestrainterfazsimplementefuncionaraacutesinrequerircambiosalprogramadedisentildeo

Estaeslainterfaz

6LaVidaSecretaDeLosObjetos

120

minAltura()devuelveunnuacutemeroindicandolaalturamiacutenimaquelaceldarequiere(enlineas)

minAnchura()devuelveunnuacutemeroindicandolaanchuramiacutenimadeestaceldaencaracteres)

dibujar(anchuraaltura)devuelveunarraydetamantildeoalturaquecontieneunaseriedecadenasquesoncadaanchuraencaracteresEstorepresentaelcontenidodelacelda

Voyahacerusointensivodemeacutetodosdeordensuperiorenarraysenesteejemployaqueseprestabienaesteenfoque

LaprimerapartedelprogramacalculaarraysdelosmiacutenimosanchosdecolumnayaltosdefilaparaunagrilladeceldasLavariablefilascontendraacuteunarraydearraysconcadaarrayinternorepresentadounafiladeceldas

functionalturasFila(filas)returnfilasmap(function(fila)returnfilareduce(function(maxcelda)returnMathmax(maxceldaminAltura())0))

functionanchurasColumna(filas)returnfilas[0]map(function(_i)returnfilasreduce(function(maxfila)returnMathmax(maxfila[i]minAnchura())0))

Usarunnombredevariablequecomienceconunguioacutenbajo(_)oqueconsistaenunsimpleguioacutenbajoesunaformadeindicar(aloslectoreshumanos)queesteargumentonoseutilizaraacute

LafuncioacutenalturasFilanodeberiacuteaserdemasiadodifiacutecildeseguirEstausareduceparacalcularlaalturamaacuteximadeunarraydeceldasyestaacutedentrodeunmapparaconseguirquesehagaparatodaslasfilasenelarrayfilas

LascosassonunpocomascomplicadasparalafuncioacutenanchurasColumnaporqueelarrayexterioresunarraydefilasnodecolumnasSemehaolvidadomencionarqueamap(comoaforEachfilterymeacutetodossimilaresdearray)selespuedepasarunsegundoargumentoesteesenlafuncioacuteneliacutendicedelelementoactualMapeandoloselementosdelaprimerafilayusandosoloelsegundoargumentodelafuncioacutenmappingcolWidths

6LaVidaSecretaDeLosObjetos

121

generaunarrayconunelementoparacadaiacutendicedecolumnaLallamadaareduceseejecutasobreelarrayexternofilasparacadaiacutendiceyseextraelaanchuradelaceldamaacutesanchaparaeseiacutendice

Aquiacuteestaelcoacutedigoparadibujarunatabla

functiondibujarTabla(filas)varalturas=alturasFilas(filas)varanchuras=anchurasColumnas(filas)

functiondibujarLinea(bloquesnumLinea)returnbloquesmap(function(bloque)returnbloque[numLinea])join()

functiondibujarFila(filanumFila)varbloques=filamap(function(celdanumColumna)returnceldadibujar(anchuras[numColumna]alturas[numFila]))returnbloques[0]map(function(_numLinea)returndibujarLinea(bloquesnumLinea))join(n)

returnfilasmap(dibujarFila)join(n)

LafuncioacutendibujarTablausalafuncioacutenauxiliarinternadibujarFilaparadibujartodaslasfilasydespueacutesunirlastodasconelcaracteresdenuevaliacutenea

LafuncioacutendibujarFilaporsimismaconviertelosobjetosceldaenlafilaabloquesquesonlosarraysdecadenasrepresentandoelcontenidodelasceldasseparadosporliacuteneaUnaceldasimplecontienesimplementeelnuacutemero3776puedeserrepresentadocomounelementosimpledearraycomo[3776]comounaceldasubrayadanosvaaocupardoslineasseraacuterepresentadaporelarray[nombre------]

LosbloquesparaunafilaquetienenlamismaalturadebenaparecerunojuntoaotroenlasalidafinalLasegundallamadaamapendibujarFilageneraestasalidaliacuteneaaliacuteneamapeandoatraveacutesdelasliacuteneasdesdeelbloquemaacutesalaizquierdayparacadaunodeestoscoleccionandounaliacuteneaqueocupalaanchuratotaldelatablaEstasliacuteneasestaacutenunidasconelcaraacutecternuevaliacuteneaparaproveerlafilaenteracomovalorderetornodedibujarFila

LafuncioacutendibujarLineaextraeliacuteneasquedebenaparecerunasjuntoaotrasdeunarraydebloquesylasuneconuncaraacutecterespacioparacrearunhuecodeuncaraacutecterentrelascolumnasdelatabla

6LaVidaSecretaDeLosObjetos

122

Ahoravamosaescribirunconstructorparalasceldasquecontienentextoqueimplementala((interfaz))paralasceldasdelatablaElconstructorseparaunacadenaenunarraydeliacuteneasusandoelmeacutetododestringsplitqueseparaunacadenaencadaocurrenciadesuargumentoyretornaunarraydepiezasElmeacutetodominAnchuraencuentralamaacuteximaanchuradeliacuteneaenestearray

functionrepetir(cadenaveces)varresultado=for(vari=0iltvecesi++)resultado+=cadenareturnresultado

functionCeldaTexto(texto)thistexto=textosplit(n)CeldaTextoprototypeminAnchura=function()returnthistextoreduce(function(anchuralinea)returnMathmax(anchuralinealength)0)CeldaTextoprototypeminAltura=function()returnthistextolengthCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistexto[i]||resultadopush(linea+repetir(anchura-linealength))returnresultado

ElcoacutedigousaunafuncioacutenauxiliarllamadarepetirquegeneraunacadenacuyovaloreselargumentocadenarepetidolasvecesqueseindicaElmeacutetododibujarseusaparaantildeadirldquoespacioldquoalasliacuteneasyaquetodasellastienelalongitudrequerida

Vamosaprobarloquehemosescritohastaahoragenerandoundamerode5x5

6LaVidaSecretaDeLosObjetos

123

varfilas=[]for(vari=0ilt5i++)varfila=[]for(varj=0jlt5j++)if((j+i)2==0)filapush(newCeldaTexto())elsefilapush(newCeldaTexto())filaspush(fila)consolelog(dibujarTabla(filas))rarr

iexclEstofuncionaPerocomotodaslasceldatienenlamismaanchuraelcoacutedigodedisentildeartablanohacealgorealmenteinteresante

LafuentededatosdelatabladelasmontantildeasqueestamostratandodegenerarestadisponibleenlavariableMOUNTAINSenel((sandbox))yademaacuteseshttpeloquentjavascriptnetcodemountainsjs[descargable]ydesdelaweb(book(httpeloquentjavascriptnetcode6[_eloquentjavascriptnetcode6_]))

QueremosdestacarlafiladearribaquecontienelosnombresdelascolumnassubrayandolasceldasconunaseriedecaracteresguioacutenNohayproblema-simplementeescribiremosuntipodeceldaquesoportesubrayado

6LaVidaSecretaDeLosObjetos

124

functionCeldaSubrayada(contenido)thiscontenido=contenidoCeldaSubrayadaprototypeminAnchura=function()returnthiscontenidominAnchura()

functionUnderlinedCell(inner)thisinner=innerUnderlinedCellprototypeminWidth=function()returnthisinnerminWidth()CeldaSubrayadaprototypeminAltura=function()returnthiscontenidominAltura()+1CeldaSubrayadaprototypedibujar=function(anchuraaltura)returnthiscontenidodibujar(anchuraaltura-1)concat([repetir(-anchura)])

UnaceldasubrayadacontieneotraceldaEstosignificaquesutamantildeomiacutenimoseraacuteelmismoqueeldelaceldainterna(llamandoatraveacutesdelosmeacutetodosdeestasceldasminAnchurayminAltura)peroantildeadeunoalaalturaparacontarelespaciotomadoporelsubrayado

Dibujarunaceldaesmuysimple-nosotrostomamoselcontenidodelaceldainterioryleconcatenamosaunaliacuteneasimpledeguiones

Teniendounmecanismodesubrayadoahorapodemosescribirunafuncioacutenquegenereunagrilladeceldasparanuestrosetdedatos

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newTextCell(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)returnnewCeldaTexto(String(row[nombre]))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrnombrealturapaiacutes-------------------------------Kilimanjaro5895Tanzaniahellipetceacutetera

6LaVidaSecretaDeLosObjetos

125

LafuncioacutenestaacutendarObjectkeysretornaunarraydenombresdepropiedadesenunobjetoLafiladearribadelatabladebecontenerceldassubrayadasquedenlosnombresalascolumnasDebajolosvaloresdetodoslosobjetosenelsetdedatosparecenceldasnormales-losextraeremosmapeandosobreelarraykeysasiacutequeestamossegurosdequeelordendelasceldaseselmismoencadafila

LatablaresultantepareceladelejemplomostradoantesexceptoporqueontieneelalineamientoaladerechadelosnuacutemeroenlacolumnaalturaVamosaconseguirloenunmomento

Gettersysetters

CuandoespecificamosunainterfazesposibleincluirpropiedadesquenosonmeacutetodosPodemostenerdefinidaminAlturayminAnchuraparasimplementealmacenarnuacutemerosPeroestopodriacutearequerirquelocalculaacuteramoseneacutel((constructor))estoantildeadecoacutedigoenelquenoesestrictamenterelevanteparaconstruirelobjetoEstopodriacuteacausarproblemassiporejemploelinteriordeunaceldasubrayadacambiaenestepuntoeltamantildeodelsubrayadodelaceldadeberiacuteacambiartambieacuten

EstohaservidocomoexcusaparaadoptarelprincipiodenoincluirnuncapropiedadesquenoseanmeacutetodosenlasinterfacesMaacutesqueunaccesodirectoaunpropiedaddevalorsimplesepuedenusarlosmeacutetodosgetAlgoysetAlgoparaleeryescribirlapropiedadEstaaproximacioacutentieneelinconvenientedequetutienesqueescribir-yleer-unmontoacutendemeacutetodosadicionales

AfortunadamenteJavaScriptproveedeunateacutecnicaquenosdalomejordeambosmundosPodemosespecificarpropiedadesquedesefueraparezcanpropiedadesnormalesperosecretamentetienen_meacutetodo_sasociadosconellas

varpila=elementos[cascaradehuevopeladuradenaranjagusano]getaltura()returnthiselementoslengthsetaltura(valor)consolelog(Ignorandoelintentodeguardarlaalturavalor)

consolelog(pilaaltura)rarr3pilaaltura=100rarrIgnorandoelintentodeguardarlaaltura100

6LaVidaSecretaDeLosObjetos

126

EnunobjetoliterallanotacioacutengetosetparapropiedadestepermiteespecificarunafuncioacutenparaserejecutadacuandolapropiedadesleiacutedaoescritaPodemosinclusoantildeadirunapropiedadaunobjetoexistenteporejemplounprototipousandolafuncioacutenObjectdefineProperty(quehemosusadopreviamenteparacrearpropiedadesnonenumerable)

ObjectdefineProperty(CeldaTextoprototypealturaPropgetfunction()returnthistextolength)

varcelda=newCeldaTexto(sinnsalida)consolelog(celdaalturaProp)rarr2celdaalturaProp=100consolelog(celdaalturaProp)rarr2

PuedesusarlapropiedadsimilarsetenelobjetopasaacutendolaadefinePropertyparaespecificarunmeacutetodosetterCuandosedefineungetterperonounsetterescribirlapropiedadessimplementeignorado

Herencia

TodaviacuteanohemosacabadoelejerciciodedisentildeodetablaAyudaalalegibilidadalinearaladerechalascolumnasconnuacutemerosDebemoscrearotrotipodeceldaqueescomoCeldaTextoperosinespacioenlapartederechaestastienenelespacioenlaparteizquierdaasiacutequealinieacutemoslasaladerecha

PodemossimplementeescribirunnuevoconstructorenteroconlostresmeacutetodosensuprototipoPerolosprototipospuedentenersusprototiposyestonospermitehaceralgointeligente

functionDCeldaTexto(texto)CeldaTextocall(thistexto)DCeldaTextoprototype=Objectcreate(CeldaTextoprototype)DCeldaTextoprototypedibujar=function(anchuraaltura)varresultado=[]for(vari=0iltalturai++)varlinea=thistext[i]||resultadopush(repetir(anchura-linealength)+linea)returnresultado

6LaVidaSecretaDeLosObjetos

127

ReutilizamoselconstructorylosmeacutetodosminAlturayminAnchuradeCeldaTextoUnaDCeldaTextoesahorabaacutesicamenteequivalenteaCeldaTextoexceptoporquesumeacutetododibujarcontieneunafuncioacutendiferente

EstepatroacutenesllamadoherenciaEstenospermitegenerartiposdedatosmuysimilaresdesdetiposdedatosexistenteconpocotrabajorelativamenteTiacutepicamenteelnuevoconstructorllamaraacutealviejoconstructor(usandoelmeacutetodocallparapermitirdarlealnuevoobjetosuvalorthis)UnavezesteconstructorsehallamadopodemosasumirquetodosloscamposqueeltipodeobjetoviejoteniacuteahansidoantildeadidosArreglamoselconstructordelprototipoparaderivarloaldelviejoprototipoasiacutequelasinstanciasdeesteprototipotendraacutentambieacutenaccesoalaspropiedadesdelviejoprototipoFinalmentepodemossobreescribiralgunadeesaspropiedadesantildeadieacutendolasanuestronuevoprototipo

AhorasiajustamosunpocolafuncioacutendatosTablaparausar_DCeldaTexto_sparaceldascuyovalorseaunnuacutemerotendremoslatablaqueestaacutebamosbuscando

functiondatosTabla(datos)varkeys=Objectkeys(datos[0])varencabezados=keysmap(function(nombre)returnnewCeldaSubrayada(newCeldaTexto(nombre)))varcuerpo=datosmap(function(row)returnkeysmap(function(nombre)varvalor=row[nombre]Estohacambiadoif(typeofvalor==number)returnnewDCeldaTexto(String(valor))elsereturnnewCeldaTexto(String(valor))))return[encabezados]concat(cuerpo)

consolelog(dibujarTabla(datosTabla(MOUNTAINS)))rarrhellippreciosatablaalineada

LaherenciaesunapartefundamentaldelatradicioacutendelaorientacioacutenaobjetosjuntoconlaencapsulacioacutenyelpolimorfismoPeromientraslasdosuacuteltimassongeneralmenteconsideradascomoideasgenialeslaherenciaesalgocontrovertido

LaprincipalrazoacutenparaestoesqueamenudoesconfundidaconelpolimorfismovendidocomounaherramientamaacutespoderosadeloqueenrealidadesyposteriormentesobreutilizadodetodaslasmalasformasposiblesMientrasquelaencapsulacioacutenyel

6LaVidaSecretaDeLosObjetos

128

polimorfismopuedenserusadosparaseparartrozosdecoacutedigodeotrosreduciendoelenmarantildeadogeneraldelprogramala((herencia))fundamentalmenteempataconamboscreandomaacutesenmarantildeado

PuedestenerpolimorfismosinherenciacomohemosvistoNotevoyadecirqueeviteslaherenciaporcompleto-YolausoregularmenteenmisprogramasPerotudebesverlacomountrucounpocosucioquetepuedeayudaradefinirnuevostiposconpococoacutedigonocomoungranprincipiodeorganizacioacutendecoacutedigoUnaformamejordeextendertiposesatraveacutesdecomposicioacutencomoCeldaSubrayadageneraotroobjetoceldasimplementeguardaacutendoloenunapropiedadyremitiendolasllamadasalosmeacutetodosasuspropios_meacutetodos_s

Eloperadorinstanceof

EsocasionalmenteuacutetilconocercuandounobjetoderivadeunconstructorespeciacuteficoParaestoJavaScripttieneunoperadorbinariollamadoinstanceof

consolelog(newDCeldaTexto(A)instanceofDCeldaTexto)rarrtrueconsolelog(newDCeldaTexto(A)instanceofCeldaTexto)rarrtrueconsolelog(newCeldaTexto(A)instanceofDCeldaTexto)rarrfalseconsolelog([1]instanceofArray)rarrtrue

EloperadorveraacuteatraveacutesdelostiposheredadosUnaDCeldaTextoesunainstanciadeCeldaTextoporqueDCeldaTextoprototypederivadeCeldaTextoprototypeEloperadorpuedeseraplicadoaconstructoresestaacutendarcomoArrayAunquecasitodoslosobjetossonunainstanciadeObject

Resumen

EntonceslosobjetossonmaacutescomplicadosdeloqueinicialmentehemostradoTienenprototiposquesonotrosobjetosyactuaraacutencomosituviesenlaspropiedadesquenotienensilastienensusprototiposLosobjetossimplestienenObjectprototypecomosuprototipo

LosconstructoresquesonfuncionescuyosnombresnormalmenteempiezanconunamayuacutesculapuedenserusadosconeloperadornewparacrearnuevosobjetosLosnuevosprototiposdelosobjetosseencontraraacutenenlapropiedadprototypedelafuncioacuten

6LaVidaSecretaDeLosObjetos

129

constructoraPuedeshacerbuenusodeestoponiendolaspropiedadesquecompartentodoslosvaloresdeuntipodadoensuprototipoEloperadorinstanceOfpuededadounobjetoyunconstructordecirtecuandoeseobjetoesunainstanciadeeseconstructor

AlgouacutetilparahacerconobjetosesespecificarunainterfazparaellosydeciratodoslosquevanacomunicarseconelobjetoquelohagansoloatraveacutesdelainterfazElrestodedetallesquemaquillantuobjetosonahoraencapsuladosocultadostraslainterfaz

AhoraqueestamoshablandoenteacuterminosdeinterfacesiquestquiendicequesolountipodeobjetopuedeimplementarseenesainterfazTenerdiferentesobjetosexpuestosalamismainterfazydespueacutesescribircoacutedigoquefuncioneencualquierobjetoeslainterfazllamadapolimoacuterficaEstoesmuyuacutetil

CuandoimplementamosmuacuteltiplestiposquedifierensoloenalgunosdetallesestopuedeayudarasimplificarhaciendoelqueelprototipodelnuevotipodeobjetoderivedelprototipodelviejoytenerunnuevoconstructorquepuedellamaralantiguoEstotedauntipodeobjetosimilaralviejoperopuedesantildeadirysobreescribirpropiedadesqueveasqueencajan

Ejercicios

Untipovector

EscribeunconstructorVectorquerepresenteunvectorenunespaciodedosdimensionesEstetomaxeycomoparaacutemetros(nuacutemeros)quesedebenguardarcomopropiedadesdelmismonombre

AntildeadealprototipoVectordosmeacutetodosmasymenosquetomanotrovectorcomoparaacutemetroydevuelvenunnuevovectorconelresultadodelasumaorestadelosdosvectores(elvectoralmacenadoenthisyelparaacutemetro)consusvaloresxey

Antildeadeunapropiedadgetterlongitudalprototipoquecalculelalongituddelvector-estoesladistanciadelpunto(xy)desdeelorigen(00)

Yourcodehere

consolelog(newVector(12)mas(newVector(23)))rarrVectorx3y5consolelog(newVector(12)menos(newVector(23)))rarrVectorx-1y-1consolelog(newVector(34)longitud)rarr5

pista

6LaVidaSecretaDeLosObjetos

130

TusolucioacutensepuedeacercarmuchoalpatroacutendelconstructorConejodeestecapiacutetulo

AntildeadirunapropiedadgetteralconstructorsepuedehacerconlafuncioacutenObjectdefinePropertyParacalcularladistanciade(00)a(xy)puedesusarelteoremadePitaacutegorasquedicequeelcuadradodeladistanciaquebuscamosesigualalasumadeloscuadradosdelacoordenada-xylacoordenada-yPortanto(htmlradic(x^2^+y^2^pass[)])(texpass[$sqrtx^2+y^2$])eselnuacutemeroquebuscasyMathsqrteslaformaenlaquecalculasunaraiacutezcuadradaenJavaScript

Otracelda

ImplementauntipodeceldallamadoCeldaEstirar(contenidoanchuraaltura)queseajustealainterfaztablacelda]descritapreviamenteenelcapiacutetuloEstadebecontenerotracelda(comohaceCeldaSurayada)yasegurarquelaceldaresultantetienealmenoslaanchurayalturadadasinclusosielcontenidodelaceldapuedasernaturalmentemenor

Yourcodehere

varsc=newCeldaEstirar(newCeldaTexto(abc)12)consolelog(scminAnchura())rarr3consolelog(scminAltura())rarr2consolelog(scdibujar(32))rarr[abc]

pista

TienesqueguardarlostresargumentosdelainstanciaenelconstructorLosmeacutetodosminAnchurayminAlturadebenllamarseatraveacutesdeloscorrespondientesmeacutetodosenelcontenidodelaceldaperoasegurarquenoseretornaunnuacutemeromenorqueeltamantildeodado(probablementeusandoMathmax)

Noolvidesantildeadirunmeacutetododrawquesimplementeredireccionelallamadaalcontenidodelacelda

Interfacesecuencia

DisentildeaunainterfazqueresumalaiteracioacutensobreunacoleccioacutendevaloresElobjetoqueproveeaestainterfazrepresentaunasecuenciaLainterfazdebemostrarcomosehaceestoposibleusandounobjetoparaiterarsobrelasecuenciamirandolosvaloresquetienenelelementoyconformadedetectarcuandosehallegadoalfinaldelasecuencia

6LaVidaSecretaDeLosObjetos

131

CuandohayasespecificadotuinterfazintentaescribirunafuncioacutenmostrarCincoquetomeelobjetosecuenciayllameaconsolelogensusprimeroscincoelementos-omenossilasecuenciatienemenosdecincoelementos

DespueacutesimplementaunobjetodeltipoArraySecquecontengaunarrayypermitalaiteracioacutensobreelarrayusandolainterfazquehasdisentildeadoImplementaotrotipodeobjetoRangoSecqueiteresobreunrangodeenteros(tomandolosargumentosdesdeyhastaensuconstructor)ensulugar

Yourcodehere

mostrarCinco(newArraySeq([12]))rarr1rarr2mostrarCinco(newRangeSeq(1001000))rarr100rarr101rarr102rarr103rarr104

pista

UnaformaderesolverestoesdaralosobjetossecuenciaunestadoimplicandoquesuspropiedadessoncambiadasmientrasseestautilizandoPuedesguardaruncontadorqueindiquecomodelejoshallegadolasecuencia

TuinterfaznecesitaraacutecontarconalmenosunaformadeobtenerelsiguienteelementoycalcularsilaiteracioacutenhallegadoalfinaldesecuenciaonoEstentadorincluirestoenunmeacutetodosiguientequeretornenulloundefinedcuandolasecuenciahayallegadoasufinPeroahoratienesunproblemacuandounasecuenciaactualmentecontienenullAsiacutequeunmeacutetodoseparado(ounapropiedadgetter)paraencontrarcuandosehallegadoalfinalesprobablementepreferible

OtrasolucioacutenesevitarcambiarelestadoenelobjetoPuedestenerunmeacutetodoparadevolverelelementoactual(sinavanzarninguacutencontador)yotroparaobtenerunanuevasecuenciaquerepresenteloselementosrestantesdespueacutesdelactual(ounvalorespecialcuandosellegaalfinaldelasecuencia)Estoesbastanteelegante-unvalorsecuenciaqueldquodependadesimismordquoinclusosidespueacutesesusadoyportantopuedasercompartidoconotrocoacutedigosinpreocuparsedequepuedepasarEstoesdesafortunadamenteinclusoalgoineficienteenunleguajecomoJavaScriptporqueimplicalacreacioacutendemuchosobjetosdurantelaiteracioacuten

6LaVidaSecretaDeLosObjetos

132

6LaVidaSecretaDeLosObjetos

133

ProyectoVidaElectronica[]Lapreguntadesilasmaacutequinaspuedenpensar[]estanrelevantecomolapreguntadesilossubmarinospuedennadarEdsgerDijkstraTheThreatstoComputingScience

EnloscapiacutetulosdeproyectodejareacutedeabrumarteconteoriacuteanuevaporunbrevemomentoyenlugardeesotrabajaremosatraveacutesdeunprogramajuntosLateoriacuteaesindispensablecuandoaprendemosaprogramarperodeberiacuteaseracompantildeadadelecturasylacomprensioacutendeprogramasnotriviales

Nuestroproyectoenestecapiacutetuloesconstruirunecosistemavirtualunmundopequentildeopobladoconbichosquesemuevenalrededoryluchanporsobrevivir

Definicioacuten

ParahacerestatareamanejablenosotrossimplificaremosradicalmenteelconceptodemundoEsdecirunmundoseraacuteunacuadriculadedosdimensionesdondecadaentidadocupauncuadrocompletodeellaEncadaturnotodoslosbichostienenoportunidaddetomaralgunaaccioacuten

PorlotantocortamosambostiempoyespacioendosunidadesconuntamantildeofijocuadrosparaespacioyturnosparatiempoPorsupuestoestoesunaburdaeimprecisaaproximacioacutenPeronuestrasimulacioacutenpretendeserentretenidanoprecisaasiacutequepodemoscortarlibrementelasesquinas

Podemosdefinirunmundoconunplanunamatrizdecadenasqueestablecelacuadriacuteculadelmundousandouncaraacutecterporcuadro

varplan=[oooo]

7ProyectoVidaElectronica

134

ElcaraacutecterenesteprogramarepresentaparedesyrocasyelcaraacutecterorepresentabichosLosespacioscomoposiblementehabraacutesadivinadosonespaciosvaciacuteos

UnamatrizunidimensionalpuedeserusadaparacrearunobjetomundoTalobjetomantieneseguimientodeltamantildeoycontenidodelmundotieneunmeacutetododetoStringqueconviertealmundonuevamenteenunacadenaimprimible(parecidaalprogramaenelquesebasoacute)demaneraquepodamosverqueacuteesloqueestaacutepasandodentroElobjetomundotambieacutentieneunmeacutetododevueltaelcualpermiteatodoslosbichoseneacuteltomarunturnoyactualizarelmundoareflejodesusacciones

Representandoelespacio

LacuadriacuteculaquemodelaelmundotieneunanchoyalturafijaLoscuadrossonidentificadosporsuscoordenadasXyYUsamosuntiposencilloVector(comolosvistosenlosejerciciosdelcapiacutetuloanterior)pararepresentarestascoordenadasenpares

functionVector(xy)thisx=xthisy=yVectorprototypeplus=function(other)returnnewVector(thisx+otherxthisy+othery)

AcontinuacionnecesitamosuntipodeobjetoquemodeleporsimismolacuadriculaUnacuadriculaespartedeunmundoperonosotrosestamoshaciendounobjetoseparado(lacuaacutelseraunapropiedaddeunobjetodelmundo)paramantenerelobjetomundosimpleElmundodebeocuparsedelascosasrelacionadasconmundoylacuadriculadebeocuparsedelascosasrelacionadasconlacuadricula

ParaalmacenarunacuadriculadevalorestenemosvariasopcionesPodemosutilizarunamatrizdematricesdefilayutilizardospropiedadesdeaccesoparallegaraunacruadriculaespeciacuteficacomoesto

vargrid=[[toplefttopmiddletopright][bottomleftbottommiddlebottomright]]consolelog(grid[1][2])rarrbottomright

Opodemosutilizarunasolamatrizconeltamantildeodeanchoxaltoydecidirqueelelementoen(xy)seencuentraenlaposicioacutenx+(yxancho)delamatriz

7ProyectoVidaElectronica

135

vargrid=[toplefttopmiddletoprightbottomleftbottommiddlebottomright]consolelog(grid[2+(13)])rarrbottomright

DadoqueelaccesorealaestamatrizseraacuteenvueltoenmeacutetodosenelobjetodetipocuadriculanoleimportaalcoacutedigoexternocualenfoquetomamosElegiacutelasegundarepresentacioacutenyaquehacequeseamuchomaacutesfaacutecilcrearlamatrizAlllamaralconstructordeArrayconunsolonuacutemerocomoargumentosecreaunanuevamatrizvaciacuteadelalongituddada

Estecoacutedigodefineelobjetodecuadriacuteculaconalgunosmeacutetodosbaacutesicos

functionGrid(widthheight)thisspace=newArray(widthheight)thiswidth=widththisheight=heightGridprototypeisInside=function(vector)returnvectorxgt=0ampampvectorxltthiswidthampampvectorygt=0ampampvectoryltthisheightGridprototypeget=function(vector)returnthisspace[vectorx+thiswidthvectory]Gridprototypeset=function(vectorvalue)thisspace[vectorx+thiswidthvectory]=value

Yaquiacuteesunapruebatrivial

vargrid=newGrid(55)consolelog(gridget(newVector(11)))rarrundefinedgridset(newVector(11)X)consolelog(gridget(newVector(11)))rarrX

Unainterfazdeprogramacioacutendebichos

BeforewecanstartontheWorld((constructor))wemustgetmorespecificaboutthe((critter))objectsthatwillbelivinginsideitImentionedthattheworldwillaskthecritterswhatactionstheywanttotakeThisworksasfollowseachcritterobjecthasanact

7ProyectoVidaElectronica

136

((method))thatwhencalledreturnsanactionAnactionisanobjectwithatypepropertywhichnamesthetypeofactionthecritterwantstotakeforexamplemoveTheactionmayalsocontainextrainformationsuchasthedirectionthecritterwantstomovein

CrittersareterriblymyopicandcanseeonlythesquaresdirectlyaroundthemonthegridButeventhislimitedvisioncanbeusefulwhendecidingwhichactiontotakeWhentheactmethodiscalleditisgivenaviewobjectthatallowsthecrittertoinspectitssurroundingsWenametheeightsurroundingsquaresbytheir((compassdirection))snfornorthnefornortheastandsoonHerestheobjectwewillusetomapfromdirectionnamestocoordinateoffsets

vardirections=nnewVector(0-1)nenewVector(1-1)enewVector(10)senewVector(11)snewVector(01)swnewVector(-11)wnewVector(-10)nwnewVector(-1-1)

Theviewobjecthasamethodlookwhichtakesadirectionandreturnsacharacterforexamplewhenthereisawallinthatdirectionor(space)whenthereisnothingthereTheobjectalsoprovidestheconvenientmethodsfindandfindAllBothtakeamapcharacterasanargumentThefirstreturnsadirectioninwhichthecharactercanbefoundnexttothecritterorreturnsnullifnosuchdirectionexistsThesecondreturnsanarraycontainingalldirectionswiththatcharacterForexampleacreaturesittingleft(west)ofawallwillget[neese]whencallingfindAllonitsviewobjectwiththecharacterasargument

sHereisasimplestupidcritterthatjustfollowsitsnoseuntilithitsanobstacleandthenbouncesoffinarandomopendirection

7ProyectoVidaElectronica

137

functionrandomElement(array)returnarray[Mathfloor(Mathrandom()arraylength)]

vardirectionNames=nneesesswwnwsplit()

functionBouncingCritter()thisdirection=randomElement(directionNames)

BouncingCritterprototypeact=function(view)if(viewlook(thisdirection)=)thisdirection=viewfind()||sreturntypemovedirectionthisdirection

TherandomElementhelperfunctionsimplypicksarandomelementfromanarrayusingMathrandomplussomearithmetictogetarandomindexWellusethisagainlaterbecauserandomnesscanbeusefulin((simulation))s

TopickarandomdirectiontheBouncingCritterconstructorcallsrandomElementonanarrayofdirectionnamesWecouldalsohaveusedObjectkeystogetthisarrayfromthedirectionsobjectwedefinedlink07_elifehtmldirections[earlier]butthatprovidesnoguaranteesabouttheorderinwhichthepropertiesarelistedInmostsituationsmodernJavaScriptengineswillreturnpropertiesintheordertheyweredefinedbuttheyarenotrequiredto

Theldquo++||s++rdquointheactmethodistheretopreventthisdirectionfromgettingthevaluenullifthecritterissomehowtrappedwithnoemptyspacearoundit(forexamplewhencrowdedintoacornerbyothercritters)

==Theworldobject==

NowwecanstartontheWorldobjecttypeThe((constructor))takesaplan(thearrayofstringsrepresentingtheworldsgriddescribedlink07elifehtmlgrid[earlier])anda((legend))_asargumentsAlegendisanobjectthattellsuswhateachcharacterinthemapmeansItcontainsaconstructorforeverycharactermdashexceptforthespacecharacterwhichalwaysreferstonullthevaluewellusetorepresentemptyspace

7ProyectoVidaElectronica

138

functionelementFromChar(legendch)if(ch==)returnnullvarelement=newlegend[ch]()elementoriginChar=chreturnelement

functionWorld(maplegend)vargrid=newGrid(map[0]lengthmaplength)thisgrid=gridthislegend=legend

mapforEach(function(liney)for(varx=0xltlinelengthx++)gridset(newVector(xy)elementFromChar(legendline[x])))

InelementFromCharfirstwecreateaninstanceoftherighttypebylookingupthecharactersconstructorandapplyingnewtoitThenweaddanoriginChar((property))toittomakeiteasytofindoutwhatcharactertheelementwasoriginallycreatedfrom

WeneedthisoriginCharpropertywhenimplementingtheworldstoStringmethodThismethodbuildsupamaplikestringfromtheworldscurrentstatebyperformingatwo-dimensionalloopoverthesquaresonthegrid

functioncharFromElement(element)if(element==null)returnelsereturnelementoriginChar

WorldprototypetoString=function()varoutput=for(vary=0yltthisgridheighty++)for(varx=0xltthisgridwidthx++)varelement=thisgridget(newVector(xy))output+=charFromElement(element)output+=nreturnoutput

A((wall))isasimpleobjectmdashitisusedonlyfortakingupspaceandhasnoactmethod

7ProyectoVidaElectronica

139

functionWall()

WhenwetrytheWorldobjectbycreatinganinstancebasedontheplanfromlink07_elifehtmlplan[earlierinthechapter]andthencallingtoStringonitwegetastringverysimilartotheplanweputin

include_codestrip_logtesttrim

varworld=newWorld(planWalloBouncingCritter)consolelog(worldtoString())rarroooo

==thisanditsscope==

TheWorld((constructor))containsacalltoforEachOneinterestingthingtonoteisthatinsidethefunctionpassedtoforEachwearenolongerdirectlyinthefunctionscopeoftheconstructorEachfunctioncallgetsitsownthisbindingsothethisintheinnerfunctiondoesnotrefertothenewlyconstructedobjectthattheouterthisreferstoInfactwhenafunctionisntcalledasamethodthiswillrefertotheglobalobject

Thismeansthatwecantwritethisgridtoaccessthegridfrominsidethe((loop))Insteadtheouterfunctioncreatesanormallocalvariablegridthroughwhichtheinnerfunctiongetsaccesstothegrid

ThisisabitofadesignblunderinJavaScriptFortunatelythenextversionofthelanguageprovidesasolutionforthisproblemMeanwhilethereareworkaroundsAcommonpatternistosayvarself=thisandfromthenonrefertoselfwhichisanormalvariableandthusvisibletoinnerfunctions

(((bindmethod)))(((this)))Anothersolutionistousethebindmethodwhichallowsustoprovideanexplicitthisobjecttobindto

7ProyectoVidaElectronica

140

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltbind(this))consolelog(testaddPropTo([5]))rarr[15]

Thefunctionpassedtomapistheresultofthebindcallandthushasitsthisboundtothefirstargumentgivento++bind++mdashtheouterfunctionsthisvalue(whichholdsthetestobject)

Most((standard))higher-ordermethodsonarrayssuchasforEachandmaptakeanoptionalsecondargumentthatcanalsobeusedtoprovideathisforthecallstotheiterationfunctionSoyoucouldexpressthepreviousexampleinaslightlysimplerway

vartest=prop10addPropTofunction(array)returnarraymap(function(elt)returnthisprop+eltthis)larrnobindconsolelog(testaddPropTo([5]))rarr[15]

Thisworksonlyforhigher-orderfunctionsthatsupportsuchacontextparameterWhentheydontyoullneedtouseoneoftheotherapproaches

Inourownhigher-orderfunctionswecansupportsuchacontextparameterbyusingthecallmethodtocallthefunctiongivenasanargumentForexamplehereisaforEachmethodforourGridtypewhichcallsagivenfunctionforeachelementinthegridthatisntnullorundefined

7ProyectoVidaElectronica

141

GridprototypeforEach=function(fcontext)for(vary=0yltthisheighty++)for(varx=0xltthiswidthx++)varvalue=thisspace[x+ythiswidth]if(value=null)fcall(contextvaluenewVector(xy))

==Animatinglife==

Thenextstepistowriteaturnmethodfortheworldobjectthatgivesthe((critter))sachancetoactItwillgooverthegridusingtheforEachmethodwejustdefinedlookingforobjectswithanactmethodWhenitfindsoneturncallsthatmethodtogetanactionobjectandcarriesouttheactionwhenitisvalidFornowonlymoveactionsareunderstood

(((grid)))ThereisonepotentialproblemwiththisapproachCanyouspotitIfweletcrittersmoveaswecomeacrossthemtheymaymovetoasquarethatwehaventlookedatyetandwellallowthemtomoveagainwhenwereachthatsquareThuswehavetokeepanarrayofcrittersthathavealreadyhadtheirturnandignorethemwhenweseethemagain

Worldprototypeturn=function()varacted=[]thisgridforEach(function(crittervector)if(critteractampampactedindexOf(critter)==-1)actedpush(critter)thisletAct(crittervector)this)

(((this)))WeusethesecondparametertothegridsforEachmethodtobeabletoaccessthecorrectthisinsidetheinnerfunctionTheletActmethodcontainstheactuallogicthatallowsthecritterstomove

7ProyectoVidaElectronica

142

WorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))if(actionampampactiontype==move)vardest=thischeckDestination(actionvector)if(destampampthisgridget(dest)==null)thisgridset(vectornull)thisgridset(destcritter)

WorldprototypecheckDestination=function(actionvector)if(directionshasOwnProperty(actiondirection))vardest=vectorplus(directions[actiondirection])if(thisgridisInside(dest))returndest

Firstwesimplyaskthecrittertoactpassingitaviewobjectthatknowsabouttheworldandthecritterscurrentpositioninthatworld(welldefineViewinalink07_elifehtmlview[moment])Theactmethodreturnsanactionofsomekind

IftheactionstypeisnotmoveitisignoredIfitismoveifithasadirectionpropertythatreferstoavaliddirectionandifthesquareinthatdirectionisempty(null)wesetthesquarewherethecritterusedtobetoholdnullandstorethecritterinthedestinationsquare

NotethatletActtakescaretoignorenonsense((input))mdashitdoesntassumethattheactionsdirectionpropertyisvalidorthatthetypepropertymakessenseThiskindofdefensiveprogrammingmakessenseinsomesituationsThemainreasonfordoingitistovalidateinputscomingfromsourcesyoudontcontrol(suchasuserorfileinput)butitcanalsobeusefultoisolatesubsystemsfromeachotherInthiscasetheintentionisthatthecrittersthemselvescanbeprogrammedsloppilymdashtheydonthavetoverifyiftheirintendedactionsmakesenseTheycanjustrequestanactionandtheworldwillfigureoutwhethertoallowit

ThesetwomethodsarenotpartoftheexternalinterfaceofaWorldobjectTheyareaninternaldetailSomelanguagesprovidewaystoexplicitlydeclarecertainmethodsandpropertiesprivateandsignalanerrorwhenyoutrytousethemfromoutsidetheobjectJavaScriptdoesnotsoyouwillhavetorelyonsomeotherformofcommunicationtodescribewhatispartofanobjectsinterfaceSometimesitcanhelptouseanamingschemetodistinguishbetweenexternalandinternalpropertiesforexamplebyprefixingallinternaloneswithanunderscorecharacter(_)Thiswillmakeaccidentalusesofpropertiesthatarenotpartofanobjectsinterfaceeasiertospot

7ProyectoVidaElectronica

143

TheonemissingparttheViewtypelookslikethis

functionView(worldvector)thisworld=worldthisvector=vectorViewprototypelook=function(dir)vartarget=thisvectorplus(directions[dir])if(thisworldgridisInside(target))returncharFromElement(thisworldgridget(target))elsereturnViewprototypefindAll=function(ch)varfound=[]for(vardirindirections)if(thislook(dir)==ch)foundpush(dir)returnfoundViewprototypefind=function(ch)varfound=thisfindAll(ch)if(foundlength==0)returnnullreturnrandomElement(found)

Thelookmethodfiguresoutthecoordinatesthatwearetryingtolookatandiftheyareinsidethe((grid))findsthecharactercorrespondingtotheelementthatsitsthereForcoordinatesoutsidethegridlooksimplypretendsthatthereisawalltheresothatifyoudefineaworldthatisntwalledinthecrittersstillwontbetemptedtotrytowalkofftheedges

==Itmoves==

WeinstantiatedaworldobjectearlierNowthatweveaddedallthenecessarymethodsitshouldbepossibletoactuallymaketheworldmove

for(vari=0ilt5i++)worldturn()consolelog(worldtoString())rarrhellipfiveturnsofmovingcritters

Thefirsttwomapsthataredisplayedwilllooksomethinglikethis(dependingontherandomdirectionthecritterspicked)

7ProyectoVidaElectronica

144

oooooooo

TheymoveTogetamoreinteractiveviewofthesecritterscrawlingaroundandbouncingoffthewallsopenthischapterintheonlineversionofthebookathttpeloquentjavascriptnet[_eloquentjavascriptnet_]

SimplyprintingoutmanycopiesofthemapisaratherunpleasantwaytoobserveaworldthoughThatswhythesandboxprovidesananimateWorldfunctionthatwillrunaworldasanonscreenanimationmovingthreeturnsperseconduntilyouhitthestopbutton

animateWorld(world)rarrhelliplife

TheimplementationofanimateWorldwillremainamysteryfornowbutafteryouvereadthelink13_domhtmldom[laterchapters]ofthisbookwhichdiscussJavaScriptintegrationinwebbrowsersitwontlooksomagicalanymore

==Morelifeforms==

ThedramatichighlightofourworldifyouwatchforabitiswhentwocrittersbounceoffeachotherCanyouthinkofanotherinterestingformof((behavior))

TheoneIcameupwithisa((critter))thatmovesalongwallsConceptuallythecritterkeepsitslefthand(pawtentaclewhatever)tothewallandfollowsalongThisturnsouttobenotentirelytrivialtoimplement

Weneedtobeabletoldquocomputerdquowith((compassdirection))sSincedirectionsaremodeledbyasetofstringsweneedtodefineourownoperation(dirPlus)tocalculaterelativedirectionsSodirPlus(n1)meansone45-degreeturnclockwisefromnorthgivingneSimilarlydirPlus(s-2)means90degreescounterclockwisefromsouthwhichiseast

7ProyectoVidaElectronica

145

functiondirPlus(dirn)varindex=directionNamesindexOf(dir)returndirectionNames[(index+n+8)8]

functionWallFollower()thisdir=s

WallFollowerprototypeact=function(view)varstart=thisdirif(viewlook(dirPlus(thisdir-3))=)start=thisdir=dirPlus(thisdir-2)while(viewlook(thisdir)=)thisdir=dirPlus(thisdir1)if(thisdir==start)breakreturntypemovedirectionthisdir

TheactmethodonlyhastoldquoscanrdquothecritterssurroundingsstartingfromitsleftsideandgoingclockwiseuntilitfindsanemptysquareItthenmovesinthedirectionofthatemptysquare

WhatcomplicatesthingsisthatacrittermayendupinthemiddleofemptyspaceeitherasitsstartpositionorasaresultofwalkingaroundanothercritterIfweapplytheapproachIjustdescribedinemptyspacethepoorcritterwilljustkeeponturningleftateverysteprunningincircles

Sothereisanextracheck(theifstatement)tostartscanningtotheleftonlyifitlookslikethecritterhasjustpassedsomekindof((obstacle))mdashthatisifthespacebehindandtotheleftofthecritterisnotemptyOtherwisethecritterstartsscanningdirectlyaheadsothatitllwalkstraightwheninemptyspace

Andfinallytheresatestcomparingthisdirtostartaftereverypassthroughthelooptomakesurethattheloopwontrunforeverwhenthecritteriswalledinorcrowdedinbyothercrittersandcantfindanemptysquare

Thissmallworlddemonstratesthewall-followingcreatures

7ProyectoVidaElectronica

146

animateWorld(newWorld([~~o]Wall~WallFolloweroBouncingCritter))

==Amorelifelikesimulation==

Tomakelifeinourworldmoreinterestingwewilladdtheconceptsof((food))and((reproduction))EachlivingthingintheworldgetsanewpropertyenergywhichisreducedbyperformingactionsandincreasedbyeatingthingsWhenthecritterhasenough((energy))itcanreproducegeneratinganewcritterofthesamekindTokeepthingssimplethecrittersinourworldreproduceasexuallyallbythemselves

IfcrittersonlymovearoundandeatoneanothertheworldwillsoonsuccumbtothelawofincreasingentropyrunoutofenergyandbecomealifelesswastelandTopreventthisfromhappening(tooquicklyatleast)weadd((plant))stotheworldPlantsdonotmoveTheyjustuse((photosynthesis))togrow(thatisincreasetheirenergy)andreproduce

TomakethisworkwellneedaworldwithadifferentletActmethodWecouldjustreplacethemethodoftheWorldprototypebutIvebecomeveryattachedtooursimulationwiththewall-followingcrittersandwouldhatetobreakthatoldworld

Onesolutionistouse((inheritance))Wecreateanew((constructor))LifelikeWorldwhoseprototypeisbasedontheWorldprototypebutwhichoverridestheletActmethodThenewletActmethoddelegatestheworkofactuallyperforminganactiontovariousfunctionsstoredintheactionTypesobject

7ProyectoVidaElectronica

147

functionLifelikeWorld(maplegend)Worldcall(thismaplegend)LifelikeWorldprototype=Objectcreate(Worldprototype)

varactionTypes=Objectcreate(null)

LifelikeWorldprototypeletAct=function(crittervector)varaction=critteract(newView(thisvector))varhandled=actionampampactiontypeinactionTypesampampactionTypes[actiontype]call(thiscrittervectoraction)if(handled)critterenergy-=02if(critterenergylt=0)thisgridset(vectornull)

ThenewletActmethodfirstcheckswhetheranactionwasreturnedatallthenwhetherahandlerfunctionforthistypeofactionexistsandfinallywhetherthathandlerreturnedtrueindicatingthatitsuccessfullyhandledtheactionNotetheuseofcalltogivethehandleraccesstotheworldthroughitsthisbinding

IftheactiondidntworkforwhateverreasonthedefaultactionisforthecreaturetosimplywaitItlosesone-fifthpointof((energy))andifitsenergyleveldropstozeroorbelowthecreaturediesandisremovedfromthegrid

==Actionhandlers==

Thesimplestactionacreaturecanperformisgrowusedby((plant))sWhenanactionobjectliketypegrowisreturnedthefollowinghandlermethodwillbecalled

actionTypesgrow=function(critter)critterenergy+=05returntrue

Growingalwayssucceedsandaddshalfapointtotheplants((energy))level

Movingismoreinvolved

7ProyectoVidaElectronica

148

actionTypesmove=function(crittervectoraction)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=1||thisgridget(dest)=null)returnfalsecritterenergy-=1thisgridset(vectornull)thisgridset(destcritter)returntrue

ThisactionfirstchecksusingthecheckDestinationmethoddefinedlink07_elifehtmlcheckDestination[earlier]whethertheactionprovidesavaliddestinationIfnotorifthedestinationisntemptyorifthecritterlackstherequired((energy))movereturnsfalsetoindicatenoactionwastakenOtherwiseitmovesthecritterandsubtractstheenergycost

Inadditiontomovingcritterscaneat

actionTypeseat=function(crittervectoraction)vardest=thischeckDestination(actionvector)varatDest=dest=nullampampthisgridget(dest)if(atDest||atDestenergy==null)returnfalsecritterenergy+=atDestenergythisgridset(destnull)returntrue

Eatinganother((critter))alsoinvolvesprovidingavaliddestinationsquareThistimethedestinationmustnotbeemptyandmustcontainsomethingwith((energy))likeacritter(butnotawallmdashwallsarenotedible)Ifsotheenergyfromtheeatenistransferredtotheeaterandthevictimisremovedfromthegrid

Andfinallyweallowourcritterstoreproduce

7ProyectoVidaElectronica

149

actionTypesreproduce=function(crittervectoraction)varbaby=elementFromChar(thislegendcritteroriginChar)vardest=thischeckDestination(actionvector)if(dest==null||critterenergylt=2babyenergy||thisgridget(dest)=null)returnfalsecritterenergy-=2babyenergythisgridset(destbaby)returntrue

Reproducingcoststwicethe((energy))levelofthenewborncritterSowefirstcreatea(hypothetical)babyusingelementFromCharonthecrittersownorigincharacterOncewehaveababywecanfinditsenergylevelandtestwhethertheparenthasenoughenergytosuccessfullybringitintotheworldWealsorequireavalid(andempty)destination

Ifeverythingisokaythebabyisputontothegrid(itisnownolongerhypothetical)andtheenergyisspent

==Populatingthenewworld==

Wenowhavea((framework))tosimulatethesemorelifelikecreaturesWecouldputthecrittersfromtheoldworldintoitbuttheywouldjustdiesincetheydonthavean((energy))propertySoletsmakenewonesFirstwellwritea((plant))whichisarathersimplelife-form

functionPlant()thisenergy=3+Mathrandom()4Plantprototypeact=function(view)if(thisenergygt15)varspace=viewfind()if(space)returntypereproducedirectionspaceif(thisenergylt20)returntypegrow

Plantsstartwithanenergylevelbetween3and7randomizedsothattheydontallreproduceinthesameturnWhenaplantreaches15energypointsandthereisemptyspacenearbyitreproducesintothatemptyspaceIfaplantcantreproduceitsimplygrowsuntilitreachesenergylevel20

Wenowdefineaplanteater

7ProyectoVidaElectronica

150

functionPlantEater()thisenergy=20PlantEaterprototypeact=function(view)varspace=viewfind()if(thisenergygt60ampampspace)returntypereproducedirectionspacevarplant=viewfind()if(plant)returntypeeatdirectionplantif(space)returntypemovedirectionspace

Wellusethecharacterfor((plant))ssothatswhatthiscreaturewilllookforwhenitsearchesfor((food))

==Bringingittolife==

AndthatgivesusenoughelementstotryournewworldImaginethefollowingmapasagrassyvalleywithaherdof((herbivore))sinitsomebouldersandlush((plant))lifeeverywhere

varvalley=newLifelikeWorld([OOOOOO]WallOPlantEaterPlant)

Letsseewhathappensifwerunthis(bookThesesnapshotsillustrateatypicalrunofthisworld)

animateWorld(valley)

7ProyectoVidaElectronica

151

OOOOOOOOOOOOOO

OOOOOOOOOOOOOOOOOOOOO

O

Mostofthetimetheplantsmultiplyandexpandquitequicklybutthentheabundanceof((food))causesapopulationexplosionofthe((herbivore))swhoproceedtowipeoutallornearlyallofthe((plant))sresultinginamassstarvationofthecrittersSometimesthe((ecosystem))recoversandanothercyclestartsAtothertimesoneofthespeciesdiesoutcompletelyIfitstheherbivoresthewholespacewillfillwithplantsIfitstheplantstheremainingcrittersstarveandthevalleybecomesadesolatewastelandAhthecrueltyofnature

==Exercises==

7ProyectoVidaElectronica

152

===Artificialstupidity===

HavingtheinhabitantsofourworldgoextinctafterafewminutesiskindofdepressingTodealwiththiswecouldtrytocreateasmarterplanteater

ThereareseveralobviousproblemswithourherbivoresFirsttheyareterriblygreedystuffingthemselveswitheveryplanttheyseeuntiltheyhavewipedoutthelocalplantlifeSecondtheirrandomizedmovement(recallthattheviewfindmethodreturnsarandomdirectionwhenmultipledirectionsmatch)causesthemtostumblearoundineffectivelyandstarveiftheredonthappentobeanyplantsnearbyAndfinallytheybreedveryfastwhichmakesthecyclesbetweenabundanceandfaminequiteintense

WriteanewcrittertypethattriestoaddressoneormoreofthesepointsandsubstituteitfortheoldPlantEatertypeinthevalleyworldSeehowitfaresTweakitsomemoreifnecessary

testno

YourcodeherefunctionSmartPlantEater()

animateWorld(newLifelikeWorld([OOOOOO]WallOSmartPlantEaterPlant))

hint

ThegreedinessproblemcanbeattackedinseveralwaysThecritterscouldstopeatingwhentheyreachacertain((energy))levelOrtheycouldeatonlyeveryNturns(bykeepingacounteroftheturnssincetheirlastmealinapropertyonthecreatureobject)Ortomakesureplantsnevergoentirelyextincttheanimalscouldrefusetoeata((plant))unlesstheyseeatleastoneotherplantnearby(usingthefindAllmethodontheview)Acombinationoftheseorsomeentirelydifferentstrategymightalsowork

7ProyectoVidaElectronica

153

MakingthecrittersmovemoreeffectivelycouldbedonebystealingoneofthemovementstrategiesfromthecrittersinouroldenergylessworldBoththebouncingbehaviorandthewall-followingbehaviorshowedamuchwiderrangeofmovementthancompletelyrandomstaggering

MakingcreaturesbreedmoreslowlyistrivialJustincreasetheminimumenergylevelatwhichtheyreproduceOfcoursemakingtheecosystemmorestablealsomakesitmoreboringIfyouhaveahandfuloffatimmobilecrittersforevermunchingonaseaofplantsandneverreproducingthatmakesforaverystableecosystemButnoonewantstowatchthat

hint

===Predators===

Anyserious((ecosystem))hasafoodchainlongerthanasinglelinkWriteanother((critter))thatsurvivesbyeatingthe((herbivore))critterYoullnoticethat((stability))isevenhardertoachievenowthattherearecyclesatmultiplelevelsTrytofindastrategytomaketheecosystemrunsmoothlyforatleastalittlewhile

OnethingthatwillhelpistomaketheworldbiggerThiswaylocalpopulationboomsorbustsarelesslikelytowipeoutaspeciesentirelyandthereisspacefortherelativelylargepreypopulationneededtosustainasmallpredatorpopulation

7ProyectoVidaElectronica

154

YourcodeherefunctionTiger()

animateWorld(newLifelikeWorld([OOOOOOOOOOO]WallTigerOSmartPlantEaterfrompreviousexercisePlant))

hint

ManyofthesametricksthatworkedforthepreviousexercisealsoapplyhereMakingthepredatorsbig(lotsofenergy)andhavingthemreproduceslowlyisrecommendedThatllmakethemlessvulnerabletoperiodsofstarvationwhentheherbivoresarescarce

Beyondstayingalivekeepingits((food))stockaliveisapredatorsmainobjectiveFindsomewaytomakepredatorshuntmoreaggressivelywhentherearealotof((herbivore))sandhuntmoreslowly(ornotatall)whenpreyisrareSinceplanteatersmovearoundthesimpletrickofeatingoneonlywhenothersarenearbyisunlikelytoworkmdashthatllhappensorarelythatyourpredatorwillstarveButyoucouldkeeptrackofobservationsinpreviousturnsinsome((datastructure))keptonthepredatorobjectsandhaveitbaseits((behavior))onwhatithasseenrecently

7ProyectoVidaElectronica

155

  • Eloquent JavaScript
  • Introduccioacuten
  • 1 Valores Tipos y Operadores
  • 2 Estructura del Programa
  • 3 Funciones
  • 4 Estructuras de Datos Objetos y Arreglos
  • 5 Funciones de Order Superior
  • 6 La Vida Secreta De Los Objetos
  • 7 Proyecto Vida Electronica