You are on page 1of 7

30/12/13

Closures en JavaScript: entindelos de una vez por todas | Variable not found

elblogdeJosM.Aguilar

Inicio Elautor Contactar

Artculos ,noticias ,curios idades ,reflexiones ...s obreelm undodeldes arrollo des oftware,internet,uotros tem as relacionados conlatecnologa
Seleccionaridioma Conlatecnologade

TraductordeGoogle Miscursos

Principal
Inicio Elautor Contactar

CursodeASP.NETMVC4

Archivodelblog
2013(88) 2012(90)
diciembre(5) noviembre(6) octubre(10)
ClosuresenJavaScript: entindelosdeunavez por... Enlacesinteresantes99 Libro:Fundamentosde JavascriptyAJAXpara desar... Enlacesinteresantes98 Enumscondesplegables automticosenMVC Enlacesinteresantes97 CursodeMVC4en CampusMVP Enlacesinteresantes96 TypeScript:unprimer vistazo Enlacesinteresantes95

ClosuresenJavaScript:entindelosdeunavezpor todas
lunes,29deoctubrede2012
Megusta Tweet 25 7 10

Variablesocial

Losclosures,encastellanocierresoclausuras,sonunapotente caractersticadeJavaScriptquetambinpodemosencontrarenotros lenguajescomoC#,ObjectiveC,Eiffelyotros.Esteconcepto,que tradicionalmentepertenecealaprogramacinfuncional,tienesuorigenen ellenguajedeprogramacinScheme. Enesteartculovamosacomenzarporidentificarenelcdigocundose producenlosclosuresparaluegoverqutienendeespecial.Despus pasaremosaveralgunoscomportamientosquenosservirnparaterminar completamentedeentendercmofuncionan.Parafinalizar,veremosun pardeejemplosdeaplicacionesprcticas.

scarSotorro Snchez
Desarrollador independiente, MCPC#

Concepto
Cuandonosacercamosporprimeravezalconceptodeclosureeshabitual encontrarnosconproblemasalahoradeentenderlo,apesardeque seguramenteenmuchasocasionesloshabremosutilizadosinsaberlo.Por estemotivo,antesdeintentardarunadefinicinmsomenosacadmica, creoqueesmuchomsprcticosaberidentificarlosclosuresenelcdigo, quealfinyalcaboesellenguajenaturaldelprogramador.

septiembre(7) julio(6) junio(11) mayo(10) abril(9) marzo(8) febrero(9) enero(9)

Eternoaprendizenestodelas tecnologas.NETyenespecial conASP.NET.Admiradordela filosofadeInternetyentusiasta delosnuevosmodelosde negocioquerigeneste mundillo.Blog: oscarsotorrio.com


QuierespublicarenVariableNotFound?

Variablenotfound
Megusta

A617personaslesgustaVariable notfound.

2011(111) 2010(87) 2009(74) 2008(90) 2007(83) 2006(39)

PluginsocialdeFacebook

ltimos30das

34,306

Publicidad

Topsemanal
Sius as GUIDs ,m uchoojo elprxim o11defebrero 13Cons ejos para com entartucdigo Enlaces interes antes 141, es pecialcam panadas Otras 101citas clebres delm undodela inform tica jqGrid:Grids es pectaculares para ASP.NETMVC,pas oa pas o Feliznavidadyprs pero 2014 WebGridenMVC3,pas o apas o

Identifiquemosloselementosqueseproducenenelcdigoanterior. Enprimerlugarpodemosverclaramentequetenemosdosfunciones,yquelafuncing r e e t ( ) est definidadentrodelafuncinp e r s o n a l i z e d G r e e t ( ) . Ensegundolugarpodemosobservarcomolafuncing r e e t ( ) utilizaensucuerpounavariablelocal pertenecientealmbitodelafuncinp e r s o n a l i z e d G r e e t ( ) . Siemprequeseproduzcanestosdoselementospodemosdecirquetenemosunclosureentremanos.Asde sencillo!Comprobemosahoracmofuncionaelcdigoquehemosvistoenlaimagenanterior. 1 2 3 4 5 6 7 8 9 / / E n o t r a p a r t e d e l c d i g o . . . v a r s a y H e l l o = p e r s o n a l i z e d G r e e t ( " s c a r " ) / * S e a l m a c e n a e n l a v a r i a b l e s a y H e l l o e l c d i g o : f u n c t i o n g r e e t ( ) { r e t u r n h e l l o + n a m e } * / a l e r t ( s a y H e l l o ( ) ) / / S e e j e c u t a e l c d i g o a n t e r i o r y / / s e m u e s t r a e n p a n t a l l a : H e l l o s c a r
?

Categoras
.net(62) ajax(18) antis pam (16) as p.net(150) as pnetm vc(158) auges (11) autobom bo (21) blogging (50) buenas prcticas (25) c# (54) cons ultas (14) cs s (18) curios idades (34) des arrollo (236) dis eo (11) enlaces (137) es tndares (12) eventos (21) frikadas (11) herram ientas (21)

Debemoscomentaraququelaaparienciamshabitualdelosclosuresescuandoutilizamosfunciones annimas,comoenelsiguienteejemplo: 1 2 3 4 5 6 7 f u n c t i o n w h a t A r e Y o u W r i t i n g A b o u t ( ) { v a r s u b j e c t = " A b o u t C l o s u r e s " v a r m e s s a g e = f u n c t i o n ( ) { r e t u r n s u b j e c t } r e t u r n m e s s a g e }


?

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

1/7

30/12/13
his torias (21) hum or(22) javas cript(29) jquery(18) m icros oft(13) m ono (15) noticias (29) novedades (47) patrones (17) pers onal (14) program acin (106) s cripting (11) s ervicios online (37) s ignalr(11) s oftwarelibre (11) s pam (17) tecnologa (12) trucos (122) tcnicas des pam (12) vacaciones (13) variablenotfound.com (16) vb.net(23) vs 2008 (28) web (52) xhtm l (17)

Closures en JavaScript: entindelos de una vez por todas | Variable not found
8 9 1 0 1 1 1 2 1 3 / / E n o t r a p a r t e d e l c d i g o . . . v a r w r i t i n g A b o u t = w h a t A r e Y o u W r i t i n g A b o u t ( ) a l e r t ( w r i t i n g A b o u t ( ) ) / / M u e s t r a e n p a n t a l l a : A b o u t C l o s u r e s

Acabamosdevercmoidentificarenelcdigocuandoseproducenlosclosurespero...qutienende particular?,quhacetanespecialalcdigoanterior? Analicemospasoapasoloquesucedesupuestamentecuandoseejecutalafuncin w h a t A r e Y o u W r i t i n g A b o u t ( ) : 1. Comienzalaejecucindelafuncinw h a t A r e Y o u W r i t i n g A b o u t ( ) . 2. Seguardaenmemoriaunavariableconelvalorstring" A b o u tC l o s u r e s " . 3. Seguardaenmemoriaunavariableconunareferenciaalcdigo: f u n c t i o n( ){r e t u r ns u b j e c t ;} . 4. Lafuncinw h a t A r e Y o u W r i t i n g A b o u t ( ) devuelveelcdigoanterior. 5. Findelaejecucindelafuncinw h a t A r e Y o u W r i t i n g A b o u t ( ) . 6. SellamaalGarbageCollectorparaqueeliminelavariables u b j e c t ,dadoquelafuncinhaterminadoy nolanecesitarhastasuprximaejecucin,dondeserotravezdefinidayasignada. Segnloexpuestoanteriormentecuandoejecutamoslaslneasdecdigosiguientes: 1 2 v a r w r i t i n g A b o u t = w h a t A r e Y o u W r i t i n g A b o u t ( ) a l e r t ( w r i t i n g A b o u t ( ) ) / / M u e s t r a e n p a n t a l l a : A b o u t C l o s u r e s
?

Literalmenteescomosiestuviramosescribiendolosiguiente. 1 2 v a r w r i t i n g A b o u t = f u n c t i o n ( ) { r e t u r n s u b j e c t } a l e r t ( w r i t i n g A b o u t ( ) ) / / M u e s t r a e n p a n t a l l a : A b o u t C l o s u r e s
?

Peroevidentemente,enestecontextoombitodelcdigo,lavariablesubjectnoexiste(oestfuerade mbito)yademssuvalorsupuestamentefuedestruidoalsalirdelafuncinw h a t A r e Y o u W r i t i n g A b o u t ( ) .Porlo tanto,cuandoseejecutalafuncinw r i t i n g A b o u t ( ) deberadarunerrortipoUncaughtReferenceError: subjectisnotdefined.Sinembargo,elcdigomuestraelmensajecorrectamente...Porqu?. CuandoJavaScriptencuentraenelcdigounclosureleindicaalGarbageCollectorquenodestruyalas variables(estnquedanguardadasoencerradas)quelafuncin"interna"necesitaparasucorrecta ejecucin.Porlotanto,apesardequelasvariablesqueestafuncinutilizaseencuentranenotrombitoen elmomentodesuejecucin,JavaScriptguardunareferenciaalvalordelasmismasyporlotantosiempre estnaccesiblesparalafuncin.Podramosdecirqueesteeselsecretoolamagiadelosclosures.

Comportamiento
Paraterminardecaptarelconceptoveamosahoraunaseriedecomportamientosocaractersticasquetienen losclosuresyquetendremosquetenersiemprepresentescuandotrabajamosconestapotenteherramienta dellenguajeJavaScript. Cmosecreanlosclosures CuandoelintrpretedeJavaScriptencuentraunclosureguardalasvariableslocalesquelasfunciones internasvananecesitar.Estoyalohemoscomentado,pero...cmoaccedenlasfuncionesaestasvariables? Veamosalgunosapuntessobreesto: Cuandounavariablelocalsealmacenaenmemoria,sistacambiaalolargodelafuncinexterna,en memoriasealmacenarelltimovalorasignadoalsalirdelafuncinexterna. Cadafuncininternaguardaunareferenciaalaposicindememoriadondesealmacenalavariable, pudiendoaccederasuvalor.

Laideaprincipalesqueelvalordelavariablepuedesermodificadaalolargodelcdigoyquelasfunciones internasguardanunareferenciaalamemoriadondeseencuentraelltimovalordelavariable que fueasignadaalsalirdelafuncinexterna.Esimportantetenerestopresentey,comoveremosahora,tiene algunoscomportamientosqueenprincipiopodransorprender. Definiromodificarlavariabledespusdelafuncininterna

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

2/7

30/12/13

Closures en JavaScript: entindelos de una vez por todas | Variable not found
Enlosejemplosdecdigoquehemoscomentadoanteriormentelavariablelocaldelafuncinexternase encontrabadefinidaantesquelafuncinanidada.Locontrarioesperfectamentevlido. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2
? f u n c t i o n p e r s o n a l i z e d G r e e t ( n a m e ) { v a r g r e e t = f u n c t i o n ( ) { r e t u r n h e l l o + n a m e } v a r h e l l o = " H e l l o " / / V a r i a b l e l o c a l d e f i n i d a d e s p u s d e l a f u n c i n a n i d a d a r e t u r n g r e e t } / / E n o t r a p a r t e d e l c d i g o . . . v a r g r e e t i n g = p e r s o n a l i z e d G r e e t ( " O s c a r " ) a l e r t ( g r e e t i n g ( ) ) / / M u e s t r a e n p a n t a l l a : H e l l o O s c a r

Comopodemosobservarnotieneningunainfluenciacuandoesdefinidalavariablelocal,lafuncininternaguardauna referenciaalaposicindememoriayutilizaelvalordelavariablecuandolanecesita.Ellectorpuedeleermssobre esteefectoysuimportanciaenelsiguienteenlace:http://www.jasoft.org/Blog/post/Elevaciondevariables %28hoisting%29enJavaScript.aspx


Porcierto,enesteejemplolafuncininternaannimautilizarealmentedosvariableslocales,h e l l o yn a m e .Los parmetrosdelafuncinexternasonconsideradoslgicamentecomovariablesdeestembito.Anteriormente seomitiestehechoparasimplificarelconceptoyexplicacin. Enelsiguienteejemplotenemosunafuncinquedefineensuinteriorunaconstante(convalor10)queser incrementadaunacantidadpasadacomoparmetroalafuncin: 1 2 3 4 5 6 7 8 9 1 0 1 1 f u n c t i o n c o n s t I n c r e a s e ( a m o u n t ) { v a r t e n = 1 0 v a r c o d e F u n c = f u n c t i o n ( ) { a l e r t ( t e n ) } t e n + = a m o u n t r e t u r n c o d e F u n c } / / E n o t r a p a r t e d e l c d i g o . . . v a r e x e c u t e = c o n s t I n c r e a s e ( 5 ) e x e c u t e ( )
?

Pensadporunmomentocualserlasalidaenpantalladeestecdigo,1015.Losquehayisrespondido15 estisenlocierto.Losqueno,esnormal,setiendeapensarqueelclosurequedaestablecidoenelcomento quesedefinelafuncinanidada,peronoesas.Comoyahemoscomentado,lafuncininterna simplementealmacenaunareferenciaalltimovalordelavariable establecidocuandolafuncin externaterminadeejecutarse. Cadallamadaesunclosuredistinto Vistoloanteriorpodrapensarsequeelclosureesunelementoglobalquepersisteentrellamadas.Noesas, porcadallamadaquehagamosalafuncinexternaestaremoscreandounnuevoeindividualclosure.Veamos elejemplosiguiente. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 f u n c t i o n p e r s o n a l i z e d G r e e t ( n a m e ) { v a r h e l l o = " H e l l o " r e t u r n f u n c t i o n ( ) { a l e r t ( h e l l o + n a m e ) } } / / C r e a m o s d o s c l o s u r e s d i s t i n t o s v a r g r e e t 1 = p e r s o n a l i z e d G r e e t ( " P e d r o " ) v a r g r e e t 2 = p e r s o n a l i z e d G r e e t ( " M a r a " ) g r e e t 1 ( ) / / M u e s t r a e n p a n t a l l a : H e l l o P e d r o g r e e t 2 ( ) / / M u e s t r a e n p a n t a l l a : H e l l o M a r a
?

Cuandotenemosvariasfuncionesinternas Veamosahoraunejemploenelquevariasfuncionesinternasguardanunareferenciaalamismavariablelocal, opodramosdecirtambinquemantienenunareferenciaalmismoclosure.Enesteejemplolafuncinexterna nodevuelveningnobjeto,vamosalmacenarlasfuncionesinternasenvariablesglobales. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 v a r g E x e c u t e 1 = n u l l v a r g E x e c u t e 2 = n u l l v a r g E x e c u t e 3 = n u l l f u n c t i o n c r e a t e C l o s u r e ( ) { v a r n u m = 1 0 g E x e c u t e 1 = f u n c t i o n ( ) { a l e r t ( n u m ) } n u m + + g E x e c u t e 2 = f u n c t i o n ( ) { a l e r t ( n u m ) } n u m = " T o m a y a ! ! ! " g E x e c u t e 3 = f u n c t i o n ( ) { a l e r t ( n u m ) } } c r e a t e C l o s u r e ( )


?

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

3/7

30/12/13
1 7 1 8 1 9

Closures en JavaScript: entindelos de una vez por todas | Variable not found
g E x e c u t e 1 ( ) g E x e c u t e 2 ( ) g E x e c u t e 3 ( )

Pienseellectorporunmomentoculserlasalidadeestescript.Efectivamente,lasalidasontresmensajes seguidosconeltexto"Tomaya!!".Notarquelastresfuncionesinternasmantienenunareferenciaalmismo valor,esdecir,lastresvariablesglobalespertenecenalmismoclosure.Dehecho,estepodraserel casodelesquemaquehemosvistoenlaimagencuandohablbamosdecomosecreanlosclosures.Pero compliquemoselcdigounpoco. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4


? v a r g E x e c u t e 1 = n u l l v a r g E x e c u t e 2 = n u l l v a r g E x e c u t e 3 = n u l l f u n c t i o n c r e a t e C l o s u r e ( ) { v a r n u m = 1 0 g E x e c u t e 1 = f u n c t i o n ( ) { a l e r t ( n u m ) } g E x e c u t e 2 = f u n c t i o n ( ) { a l e r t ( + + n u m ) } g C l o s u r e 3 = f u n c t i o n ( ) { a l e r t ( n u m = " T o m a y a ! ! ! " ) } } c r e a t e C l o s u r e ( ) g E x e c u t e 1 ( ) / / E j e c u t a e l c d i g o : f u n c t i o n ( ) { a l e r t ( n u m ) } / / > M u e s t r a e n p a n t a l l a : 1 0 g E x e c u t e 2 ( ) / / E j e c u t a e l c d i g o : f u n c t i o n ( ) { a l e r t ( + + n u m ) } / / > M u e s t r a e n p a n t a l l a : 1 1 g E x e c u t e 3 ( ) / / E j e c u t a e l c d i g o : f u n c t i o n ( ) { a l e r t ( n u m = " T o m a y a ! ! ! " ) } / / > M u e s t r a e n p a n t a l l a : T o m a y a ! ! ! / / Q u m o s t r a r a h o r a l a s i g u i e n t e l i n e a d e c d i g o . . . ? g E x e c u t e 1 ( )

Sivolvemosaejecutarelcdigodelafuncing E x e c u t e 1 ( ) obtenemoselmensaje"Tomaya!!".Estoes totalmentelgicoporqueestafuncintieneunareferenciaalmismoclosurequeg E x e c u t e 3 ( ) quefuelaltima funcinenmodificarelclosurequecomparten. Todavariablepuedeperteneceralclosure Debemostenerencuentaquetodotipodevariablequesedeclaredentrodelmbitodelafuncin externayseautilizadaporlafuncinanidadaperteneceralclosure.Estopuededaralgunos resultadosinesperadosporcreacindeclosuresnoprevistos.Porejemplo,cuandoejecutamosbucles debemosprestaratencinsidentrodelafuncininternautilizamoslavariablecontadordelbucle:staesa todoslosefectosunavariablelocaldelafuncinexternayporlotantoperteneceralclosure. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 f u n c t i o n t e s t L o o p ( l e n g t h ) { v a r l i s t = n e w A r r a y ( ) f o r ( v a r i = 0 i < = l e n g t h i + + ) { l i s t [ i ] = " I t e m " + i } r e t u r n f u n c t i o n ( ) { a l e r t ( " i = " + i + " \ n " + " l i s t [ " + i + " ] = " + l i s t [ i ] ) } } v a r e x e c u t e = t e s t L o o p ( 5 ) e x e c u t e ( ) / * S a l i d a d e l p r o g r a m a i = 6 l i s t [ 6 ] = u n d e f i n e d * /
?

Comopodemosobservarelcontadortambinpertenecealclosureyestdisponibleparalafuncininterna fueradelmbitodelafuncinexterna.Adems,yaquescuandotenemosquetenercuidado,elltimovalor paraestavariablees6porqueelbucleejecutaunavezmslainstruccini + + paraluegorealizarla comprobacini < =l e n g t h ysalirdelmismo.

Aplicacionesprcticas
Ahoraqueseguramentequeyahemosentendidocmosecomportanlosclosures,pasemosaalgoms prctico.Enseguidavamosaveralgunosejemplosdondepodemoscomprobarenelcampodebatallala potenciadeestacaractersticadellenguaje.Tengaellectorencuentaqueaplicacionessobreesteconcepto puedenhabertantascomolasnecesidadesoimaginacindelosprogramadores,aquveremossoloalgunas. Ejecutarfuncionesretardadas Quizsesteseaelejemploprcticomsclsicoyqueellectorseguramenteyaconocer.Enocasionesen nuestrocdigoJavaScriptpodemosnecesitarrealizaroperacionesconretardo,paraelloJavaScriptnosprovee delasfuncioness e t T i m e o u t ( ) ys e t I n t e r v a l ( ) .

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

4/7

30/12/13

Closures en JavaScript: entindelos de una vez por todas | Variable not found
Normalmentellamaremosaestasfuncionespasndolecomoparmetroselnombredelafuncinaejecutaryel tiempoderetardoenmilisegundos.Elproblemaaresolveresquesucedesilafuncinquequeremosejecutar conretardotomaunoomsparmetros.Enprincipionotenemosformadepasarlelosparmetrosanuestra funcindadoques e t T i m e o u t ( ) ys e t I n t e r v a l ( ) sloadmitenelnombredelafuncincomoprimerparmetro. Estoesfcilderesolverconunclosure. 1 2 3 4 5 6 7 8 9 1 0 1 1 f u n c t i o n a d d i t i o n N u m b e r ( a , b ) { r e t u r n f u n c t i o n ( ) { a l e r t ( a + " + " + b + " = " + ( a + b ) ) } } v a r e x e c u t e = a d d i t i o n N u m b e r ( 1 0 , 4 0 ) s e t T i m e o u t ( e x e c u t e , 3 0 0 0 ) / / D e s p u s d e 3 s e g u n d o s s e m u e s t r a / / e n p a n t a l l a : 1 0 + 4 0 = 5 0
?

Accesodesdemiembrosprivadosamiembrospblicos Enunartculoanteriorcuandohablamosdelasfuncionesconstructorascomentamosquedesdelosmtodos privadosnopodamosteneraccesoalaspropiedadespblicasdelobjetocreado.Retomandoelejemplode cdigoquevimosenaquelartculoveamoscmosaltarnosestepequeoescollo: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 f u n c t i o n C o n s t r u c t o r ( m s j P r i v a d o , m s j P u b l i c o ) { v a r p r o p i e d a d P r i v a d a = m s j P r i v a d o t h i s . p r o p i e d a d P u b l i c a = m s j P u b l i c o v a r t h a t = t h i s / * L a v a r i a b l e ' t h a t ' s e r g u a r d a d a e n e l c l o s u r e p a r a s e r u t i l i z a d a e n s u m o m e n t o p o r l a f u n c i n m e t o d o P r i v a d o ( ) * / v a r m e t o d o P r i v a d o = f u n c t i o n ( ) { a l e r t ( p r o p i e d a d P r i v a d a ) a l e r t ( t h a t . p r o p i e d a d P u b l i c a ) } t h i s . m e t o d o P u b l i c o = f u n c t i o n ( ) { m e t o d o P r i v a d o ( ) } } v a r o b j = n e w C o n s t r u c t o r ( " m e n s a j e p r i v a d o " , " m e n s a j e p b l i c o " ) o b j . m e t o d o P u b l i c o ( ) / * M u e s t r a e n p a n t a l l a d o s m e n s a j e s s e g u i d o s : m e n s a j e p r i v a d o m e n s a j e p b l i c o * /
?

PersonalizareventosparaobjetosdeterminadosdelDOM SupongamosquequeremosencapsularenobjetosdelDOMlatpicafuncionalidadparaquecuandoelratnse posicionesobreunelementoHTMLstecambieeltextodecoloryelestilodelpuntero,mientrasquecuandoel ratnabandoneelelemento,eltextoypunterovuelvenasuestadoanterior. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4


? / / A s o c i a u n o b j e t o a u n e v e n t o p e r s o n a l i z a d o f u n c t i o n f u n c D e l e g a t e ( o b j , m e t h o d N a m e ) { / / { 1 } r e t u r n f u n c t i o n ( e ) { e = e | | w i n d o w . e v e n t r e t u r n o b j [ m e t h o d N a m e ] ( t h i s , e ) / / { 2 } } } / / C r e a u n o b j e t o y e n l a z a l o s e v e n t o s d e l D O M c o n l o s e v e n t o s p e r s o n a l i z a d o s f u n c t i o n D O M O b j e c t ( i d ) { t h i s . _ e l e m e n t = d o c u m e n t . g e t E l e m e n t B y I d ( i d ) i f ( t h i s . _ e l e m e n t ) { / / { 3 } t h i s . _ e l e m e n t . o n m o u s e o v e r = f u n c D e l e g a t e ( t h i s , " c u s t o m O n M o u s e O v e r " ) / / { 4 } t h i s . _ e l e m e n t . o n m o u s e o u t = f u n c D e l e g a t e ( t h i s , " c u s t o m O n M o u s e O u t " ) } } / / D e f i n i m o s e l c d i g o d e n u e s t r o s e v e n t o s p e r s o n a l i z a d o s D O M O b j e c t . p r o t o t y p e . c u s t o m O n M o u s e O v e r = f u n c t i o n ( o b j , e v e n t ) { o b j . s t y l e . c u r s o r = " p o i n t e r " o b j . s t y l e . c o l o r = " r e d " } D O M O b j e c t . p r o t o t y p e . c u s t o m O n M o u s e O u t = f u n c t i o n ( o b j , e v e n t ) { o b j . s t y l e . c u r s o r = " p o i n t e r " o b j . s t y l e . c o l o r = " b l a c k " } / / A h o r a p o d e m o s a c t i v a r t o d o e s t e m e c a n i s m o p a r a d i s t i n t o s e l e m e n t o s d e n u e s t r a p g i n a v a r m y D i v = n e w D O M O b j e c t ( " a D i v " ) v a r m y B u t t o n = n e w D O M O b j e c t ( " a B u t t o n " )

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

5/7

30/12/13

Closures en JavaScript: entindelos de una vez por todas | Variable not found

1. Aquesdondeseproduceelclosure.Comosepuedeapreciarlafuncininternaguardarunareferencia aunobjetopasadocomoparmetroyalnombredeunafuncinqueenestecasoserelnombrede nuestroeventopersonalizado.Nteseunavezms,aqusimplementeseestcreandoelclosurey devolviendouncdigo,queserejecutadomstarde,parecidoa: o b j e t o . e v e n t o P e r s o n a l i z a d o ( e l e m e n t o H T M L ,e v e n t o D O M ) .Aunqueestecdigoseejecutedespus,la funcinseguirteniendoaccesoalobjetoyalvalordelacadenaquerepresentaelnombredelevento. 2. Aunquelapalabrareservadat h i s puedaparecerqueseutilizaaqu,recordemosqueenestemomento slosecreaelclosureysedevuelveuncdigoqueserejecutadoaposteriori.Enelmomentode ejecutarteestecdigo,cuandouneventodelDOMsedispare(ej:onclick),t h i s harreferenciaal elementoHTMLquedisparaeleventodelDOM . 3. EnestemomentoasignamosaloseventosdelDOMquenosintereseelcdigodevueltopor f u n c D e l e g a t e .Lohemosmencionadoantes,estecdigoserdelestilo: o b j e t o . e v e n t o P e r s o n a l i z a d o ( e l e m e n t o H T M L ,e v e n t o D O M ) .Porlotanto,cuandosedispareunevento delDOM,comoelonclick,estaremosllamandoaunafuncinquehacelasvecesdenuestro eventopersonalizado. 4. Aqut h i s hacereferenciaalobjetocreadoconlafuncinconstructoraD O M O b j e c t ( i d ) . Seguramenteellectorconozcaotrasformasmssencillaspormediodellamadassucesivasafuncionesde implementarelmismocomportamiento.Laventajadehacerlodeestaformaesqueestamosencapsulandola funcionalidadconlospropiosobjetosdelDOM,loquenosproporcionamsrobustezymantenibilidaddel cdigoyademsnospermitedispararloseventospersonalizadoscuandolonecesitemos: 1 2 v a r m y D i v = n e w D O M O b j e c t ( " a D i v " ) m y D i v . c u s t o m O n C l i c k ( m y D i v . _ e l e m e n t , n u l l )
?

Referencias
Muyrecomendableeslalecturadellibro"FundamentosdeJavaScriptyAJAXparadesarrolladoresy diseadoresweb",enelquesepuedeencontrarunainteligentetcnicaparaencapsularmiembrosde objetospormediodeclosuresademsdeseruncompletsimotratadosobreJavaScript. Siellectorquiereprofundizarmssobreesteconceptolerecomiendoelsiguienteenlace: http://dmitrysoshnikov.com/ecmascript/chapter6closures/ Alfinaldelsiguienteenlaceseutilizaunpatrnpormediodeclosuresparaimplementarpropiedades privadas,pblicasyconprivilegiosenobjetosJavaScript: http://www.crockford.com/javascript/private.html Autor:scarSotorroSnchez PublicadoenVariablenotfound
Megusta Tweet 25 7 10

Estoscontenidossepub licanb ajounalicenciadeCreativeCom m ons

PublicadoporJosM.Aguilaralas9:10a.m. Etiquetas:colaboraciones,javascript,oscarsotorrio 6Comentarios: SergioLendijo... Oscar,superpost! Muybienexplicadoyademssenotaquetelohaspreparadoaconciencia. Josetienequeestarorgullosodetanilustrecolaboracin) martes,30octubre,2012 Oscar.SSdijo... MuchasgraciasSergio, Laverdadesqueestscosasefectivamentellevansutiempo) YJosMaratambinsellevalosuyoporemaildebatiendoconmigocualdebepuedeserelenfoquems pedaggicoymuchasotrascosas.Asqueelqueestorgullososoyyodecolaborarconl.Siempre aprendoalgo:) martes,30octubre,2012 SergioLendijo... HolaOscar: Unaspreguntasalrespectodetuartculo: 1.Yodigoquehehechoun"closure"slocuandolafuncinexternahafinalizadosuejecucinperola funcininternatienequeseguirteniendoaccesoavariablesdeunmbitosuperior.Esdecir,slopor utilizarunavariabledeunmbitosuperioryo,personalmente,nohablode"closure".Paramtieneque habervidadeunafuncininternamsalldelavidadeunafuncinexternayconaccesoavariablesde unmbitosuperior.Uff,esperohabermeexplicado.Squeesunmatizmuytonto,perotqueopinas? 2.LociertoesqueelgarbagecollectordeJS...ahest,tampocohehechoningunaaplicacincon memoryleaks"aparentes"peromesurgeladudaelgarbagecollectordeJSessimilaralde.NET?Es decir,cuandonohayareferenciasalafuncininternadesdefueraseliberarentonceselclosure? Unsaludo. martes,30octubre,2012

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

6/7

30/12/13

Closures en JavaScript: entindelos de una vez por todas | Variable not found
Oscar.SSdijo... HolaSergio, 1Nossiteheentendidobien.Perositedascuentaapuntasdoselementosparaquehayaunclosure. "...tienequehabervidadeunafuncininternamsalldelavidadeunafuncinexterna"y"conacceso avariablesdeunmbitosuperior". Alfinal,creoqueeslomismoquesehacomentadoenelartculoperodichodeotraforma.Esdecir, formasdeexpresarlopuedehabermuchasyseguroquemejoresquelaqueseutilizaenelartculo,de hecho,comosecomentaenelpost,nosepretendedarunadefinicinacadmica,soloqueseentienda elconcepto. Aqutienesotraformadeverlohablandodelverdaderombitodelasvariables. http://www.jasoft.org/Blog/post/PermaLinkaspxguid=559517d8957941bd9e2c36569dc.aspx 2Buenapregunta:) HastadondeyollegoenJavaScriptlamemoriaseasignaalosobjetosensucreacinyesreclamadopor elnavegadorcuandonohaymsreferenciasalosmismos. Aunquecreoquedependeunpocodelexplorador,porejemplo,enInternetExploreryMozillaFirefoxse utilizaelrecuentodereferenciasparamanejarlamemoriadelosobjetosDOM. Creoquelapreguntaesbuenayhabraquevercomoserelacionatodoestoconlosclosures.Nomeha dadotiempoaleerloperopareceinteresanteesteartculo. http://www.ibm.com/developerworks/web/library/wamemleak/ Unsaludo martes,30octubre,2012 SergioLendijo... Graciasporresponder,Oscar. Voyaleerlosenlacesporquepareceninteresante.Respectoalosclosuresestamosenlnea,alfinalson definicionessimilares.Yencuantoalosmemoryleakpues...aleertoca!) martes,30octubre,2012 pablillo.esdijo... Wooo...Simplementeincreiblelaexplicacion...lamejordetodalared sbado,28septiembre,2013 Enviarunnuevocomentario Backlinks: Blogueasobreestetema!

AppDevelopment Software
www.wakanda.org Buildbusinesswebapplicationswithnothing butJS.Freedownload.

Entradamsreciente

Pginaprincipal

Entradaantigua

Variablenotfound,20062013::UsandoBlogger::TodosloscontenidossonCreativeCommons

www.variablenotfound.com/2012/10/closures-en-javascript-entiendelos-de.html

7/7

You might also like