<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6000240755870692859</id><updated>2011-12-10T07:32:31.666-08:00</updated><category term='avanzado'/><category term='javascript'/><category term='metaprograming'/><category term='3d'/><category term='principiante'/><category term='lenguaje'/><category term='tutorial'/><category term='Beyond JS'/><category term='editores'/><category term='textos'/><category term='Douglas Crockford'/><category term='functions'/><category term='lambda'/><category term='teorias'/><category term='curry'/><category term='bookmarklets'/><category term='librerias'/><category term='DSL'/><category term='funciones'/><category term='bespin'/><category term='basico'/><category term='ocr'/><category term='mozilla'/><category term='objetos'/><category term='closures'/><category term='Y combinator'/><category term='scripts'/><title type='text'>Javascript</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-3650634347703916830</id><published>2011-11-05T13:49:00.000-07:00</published><updated>2011-11-05T13:52:37.231-07:00</updated><title type='text'>JavaScript Server Side - Alejandro Hernandez</title><content type='html'>Tercer tech update!!!!!&lt;div&gt;&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/JWEfrzdHtng" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-3650634347703916830?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/3650634347703916830/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/11/javascript-server-side-alejandro.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/3650634347703916830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/3650634347703916830'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/11/javascript-server-side-alejandro.html' title='JavaScript Server Side - Alejandro Hernandez'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/JWEfrzdHtng/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-4339074300161550885</id><published>2011-10-29T13:42:00.000-07:00</published><updated>2011-10-29T13:44:43.618-07:00</updated><title type='text'>Funciones de Alto Orden en JavaScript - Alejandro Hernandez</title><content type='html'>Segundo tech update!!!!!&lt;div&gt;&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/7Bp_9uQaTlI" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-4339074300161550885?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/4339074300161550885/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/10/funciones-de-alto-orden-en-javascript.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4339074300161550885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4339074300161550885'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/10/funciones-de-alto-orden-en-javascript.html' title='Funciones de Alto Orden en JavaScript - Alejandro Hernandez'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/7Bp_9uQaTlI/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-5573380632296682900</id><published>2011-10-17T21:32:00.000-07:00</published><updated>2011-10-17T21:39:12.893-07:00</updated><title type='text'>JavaScript - Alejandro Hernández</title><content type='html'>Tengo el agrado de contarles que se hizo realidad uno de mis sueños más grandes. Poder comenzar a dar una serie de charlas sobre JavaScript en una gran multinacional. En este momento me encuentro trabajando en Globant, empresa Argentina dedicada al outsourcing de recursos en tecnologías de la información y, hasta ahora, el mejor lugar que conozco para trabajar.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sin más introducción, aquí el video.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.youtube.com/watch?v=d9CJfavZnC0"&gt;http://www.youtube.com/watch?v=d9CJfavZnC0&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/d9CJfavZnC0" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-5573380632296682900?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/5573380632296682900/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/10/javascript-alejandro-hernandez.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5573380632296682900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5573380632296682900'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/10/javascript-alejandro-hernandez.html' title='JavaScript - Alejandro Hernández'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/d9CJfavZnC0/default.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8981405163341772816</id><published>2011-10-05T21:04:00.001-07:00</published><updated>2011-10-05T21:09:04.506-07:00</updated><title type='text'>Steve Jobs</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/-drvyveL0unQ/To0pAkT3ohI/AAAAAAAAACw/wff59UMRuzY/s1600/Imagen%2B12.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 238px;" src="http://1.bp.blogspot.com/-drvyveL0unQ/To0pAkT3ohI/AAAAAAAAACw/wff59UMRuzY/s320/Imagen%2B12.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5660225396398334482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 102, 102); font-family: 'Lucida Grande', Tahoma, Arial, Verdana, sans-serif; font-size: 12px; line-height: 18px; background-color: rgb(255, 255, 255); "&gt;Stay hungry, stay foolish!!!!!!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 12px; line-height: 18px;"&gt;Nuestra industria ha perdido un grande. Revolucionario, creativo e inspirador son apenas unas pocas de las miles de palabras que se vienen a mi cabeza en este momento, para describir a la gran persona que fue Steve Jobs, sin duda influyó de manera importante en nuestra historia y por ello será recordado siempre.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 12px; line-height: 18px;"&gt;Un gran saludo Steve..... y una cosa más.... mi más sincera admiración por el trabajo de tu vida.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 12px; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 102, 102); font-family: 'Lucida Grande', Tahoma, Arial, Verdana, sans-serif; font-size: 12px; line-height: 18px; background-color: rgb(255, 255, 255); "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8981405163341772816?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8981405163341772816/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/10/steve-jobs.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8981405163341772816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8981405163341772816'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/10/steve-jobs.html' title='Steve Jobs'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-drvyveL0unQ/To0pAkT3ohI/AAAAAAAAACw/wff59UMRuzY/s72-c/Imagen%2B12.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-5363131056845066476</id><published>2011-09-02T00:23:00.000-07:00</published><updated>2011-09-02T00:29:39.012-07:00</updated><title type='text'>A recoger la basura</title><content type='html'>&lt;div&gt;&lt;i&gt;Este post surgió por una consulta en mi trabajo asi que Gracias Guille por la idea!&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Vamos a hablar un poco del famosisimo proceso de Garbage colection de javascript&lt;/div&gt;&lt;div&gt;Como sabrán (deberían) el Garbage colector de un lenguage es el encargado de liberar la memoria que ya no se está utilizando, pero... como es que hace esto?&lt;/div&gt;&lt;div&gt;La parte dificil aqui es decidir cual es la memoria que se debe liberar y cual no, entonces es necesario un algoritmo para marcar que objetos en memoria no son más necesarios.&lt;/div&gt;&lt;div&gt;En las primeras implementaciones (javascript 1.1 Netscape 3) el garbage collector utilizaba un mecanismo llamado &lt;/div&gt;&lt;div&gt;&lt;b&gt;Reference Counting&lt;/b&gt; (Conteo de referencias) el cual basicamente mantiene un registro de la cantidad de variables que apuntan a un objeto en memoria.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;var a = {}; &lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;//creamos un objeto en memoria y lo apuntamos desde la variable a&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;// la cantidad de variables (referencias al objeto) es 1&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;var b=a;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;//con b apuntamos al mismo objeto aumentando su reference counting en 1&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;//por lo tanto ahora 2 variables le apuntan&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;b=null&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;//desapuntamos b, decrementa el conteo de referencias nuevamente a 1&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;a=null&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;//desapuntamos el objeto y su conteo de referencias cae a 0&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;// ahora es un objeto en memoria no apuntado por nadie propenso&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span"  &gt;// a la recolección de basura (y recupero del espacio en memoria)&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sin embargo el algoritmo de reference counting, tiene un problema Gravisimo&lt;/div&gt;&lt;div&gt;las referencias ciclicas&lt;/div&gt;&lt;div&gt;esto es&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;var a={color:'rosa'};&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;var b={color:'rojo'};&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;var c={color:'negro'};&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//creo 3 objetos y los apunto con 3 variables&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//cada objeto tiene su reference count en 1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//RC(rosa):1 RC(rojo):1 RC(negro):1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;a.next=b;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//ahora apunto con a.next al objeto rojo  &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//RC(rosa):1 RC(rojo):2 RC(negro):1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;b.next=c;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//con b.next apunto al objeto negro&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//RC(rosa):1 RC(rojo):2 RC(negro):2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;c.next=b;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//con c.next apunto nuevamente al objeto rojo&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//RC(rosa):1 RC(rojo):3 RC(negro):2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//desapunto todas las variables&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;a=null;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;b=null;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;c=null;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//decrementando en 1 todos los RC&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//RC(rosa):0 RC(rojo):2 RC(negro):1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//cuando el proceso de garbage colector note que el objeto &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//rosa no es apuntado por nadie lo eliminará, eliminando &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//el puntero next al objeto rojo decrementando su RC nuevamente&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//RC(rosa):0 RC(rojo):1 RC(negro):1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//pero rojo y negro continuan apuntandose entre si por tanto &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//sus RC jamas decaen a 0 y no son liberados&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;//MEMORY LEAK!!!!!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Los objetos apuntados ciclicamente no pueden ser liberados mediante este algoritmo, por lo cual muchos nisiquiera aceptan a Reference Counting como un algoritmo de Garbage Collection.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Por suerte los tiempos cambiaron y la mayoria de los interpretes de javascript han decidido actualizar sus algoritmos de garbage collection a algo mucho mas efectivo llamado &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" &gt;Mark-and-sweep&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Que basicamente toma un contexto y revisa para todas las variables de ese contexto, todos los objetos en memoria alanzables desde esas variables y los marcan como "ALCANZABLE" desde el contexto del programa.&lt;/div&gt;&lt;div&gt;luego recorre la memoria en busca de los objetos no marcados como "ALCANZABLES" y los borra.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;es un algoritmo que requiere mucho mas trabajo pero es más efectivo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;tienen una mejor explicación &lt;a href="http://docstore.mik.ua/orelly/webprog/jscript/ch11_03.htm"&gt;aqui&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;como pueden ver en&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/intl/es-ES/apis/v8/embed.html#handles"&gt;http://code.google.com/intl/es-ES/apis/v8/embed.html#handles&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Google chrome utiliza garbage collection por Mark-and-sweep &lt;/div&gt;&lt;div&gt;"he V8 garbage collector reclaims memory used by objects that can never again be accessed."&lt;/div&gt;&lt;div&gt;y como lo hace en&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/intl/es-ES/apis/v8/design.html#garb_coll"&gt;http://code.google.com/intl/es-ES/apis/v8/design.html#garb_coll&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" &gt;Linda historia... pero es "historia"?&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En cuanto al lenguage si, PEEEERO y este es un gran pero, dependiendo del entorno en el que uses javascript esto puede variar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" &gt;&lt;b&gt;Para los navegadores?&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lamentablemente no, todos los navegadores aún continuan utilizando Reference Counting para los objetos del DOM&lt;/div&gt;&lt;div&gt;por lo tanto basta apuntar a un objeto del DOM desde javascript y al objeto javascript desde el DOM y habremos generado un memory leak&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;veamos un ejemplo&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;var tryingToLeak = function(){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    obj=document.getElementById("btnClearLog");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    //apunto al DOM desde JS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    document.getElementById("btnClearLog").expandoProperty=obj;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    //apunto a JS desde el DOM&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    obj.bigString=new Array(10000).join(new Array(2000).join("XXXXX"));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    //Consumo memoria en JS&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;};&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;tryingToLeak();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;cada vez que ejecutamos el codigo anterior el proceso reclama 200mb de ram que no devuelve jamas&lt;/div&gt;&lt;div&gt;pueden probarlo utilizando el "Administrador de tareas de Google Chrome"&lt;/div&gt;&lt;div&gt;por mas que la variable de JS ya no tenga visibilidad el objeto del DOM continua con un RC mayor a 1 y por tanto no es sujeto a ser eliminado.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A continuación les dejo dos códigos que demuestran que no se producen memory leaks en javascript&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;var tryingToLeak = function(){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;  for(var i=0; i&amp;lt;=1000; i++){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    var str=new Array(1000).join(new Array(2000).join("XXXXX"));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;};&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;tryingToLeak();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;var tryingToLeak = function(){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;  for(var i=0; i&amp;lt;=1000; i++){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    var arr=[];&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    for(var j=0; j&amp;lt;=1000;j++){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;      arr.push(new Array(2000).join('XXXXX'));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;    }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;  }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;};&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;tryingToLeak();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Saludos&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-5363131056845066476?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/5363131056845066476/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/09/recoger-la-basura.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5363131056845066476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5363131056845066476'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/09/recoger-la-basura.html' title='A recoger la basura'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-6065044494155465038</id><published>2011-04-30T23:41:00.000-07:00</published><updated>2011-05-02T08:28:57.969-07:00</updated><title type='text'>1, 2, 3..... TODOS A LA CHURCH!</title><content type='html'>&lt;i&gt;&lt;span class="Apple-style-span"&gt;"Estoy escribiendo la función que nunca nadie escribió.... pero no puedo terminarla"&lt;/span&gt;&lt;/i&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cuando hablamos de Javascript hablamos de funciones lambda, pero... de donde viene ese lambda?.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;El &lt;a href="http://es.wikipedia.org/wiki/C%C3%A1lculo_lambda"&gt;calculo lambda&lt;/a&gt; es un sistema formal introducido por &lt;a href="http://es.wikipedia.org/wiki/Alonzo_Church"&gt;Alonzo Church&lt;/a&gt; allá por los años 30 para modelar la matemática (WOW! Que ambición!) pero se volvió suceptible a la &lt;a href="http://es.wikipedia.org/wiki/Paradoja_de_Russell"&gt;paradoja de Russell&lt;/a&gt; y entonces lo uso para estudiar la computabilidad.&lt;/div&gt;&lt;div&gt;Ahora... cómo es el calculo lambda?&lt;/div&gt;&lt;div&gt;Bueno Alonzo introdujo algunos conceptos muy complejos en las funciones, conceptos que ya estaban ahi pero que nadie habia notado.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;Los tres conceptos del cálculo lambda&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Dada la función &lt;i&gt;suma(x,y)=x+y&lt;/i&gt; Church nota los siguientes puntos&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Las funciones no necesitan ser explícitamente nombradas:&lt;/b&gt; esto es: suma(x,y)=f(x,y)=s(x,y)=x+y, no importa el nombre de la función, sino lo que esta hace.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;El nombre que se le asigne a los parámetros es irrelevante:&lt;/b&gt; quiere decir que suma(x,y)=x+y === suma(u,v)u+v (simple)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Toda función que recibe más de un argumento puede ser reescrita como una función que recibe un solo argumento que devuelve otra función que recibe un argumento, que devuelve otra función que recibe un argumento, que devuelve otra......(asi sucesivamente).... hasta que la ultima es la que realiza la operación:&lt;/b&gt; Y aqui ya necesitamos de la notación de javascript para ver de que estamos hablando&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function suma(x,y){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return x+y;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function sumador(x){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return function(y){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;return x+y;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var sumador5 = sumador(5);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(suma(5,4)); //9&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(sumador5(4)); //9&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;a este proceso se le conoce como currificación (nombre horrible) me quedo con el ingles currying, concepto del que ya hemos hablado en este &lt;a href="http://javascriptexperts.blogspot.com/2009/03/currying-functions.html"&gt;post&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con estas tres observaciones Church decide expresar sus números para realizar una aritmética básica, para ello define la función &lt;i&gt;Identidad&lt;/i&gt; de la forma&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function I(x){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return x;&lt;/div&gt;&lt;div&gt;} &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ahora bien, los números de Church propiamente dichos se expresan así:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El número &lt;i&gt;N&lt;/i&gt; de Church es una función que recibe una función &lt;i&gt;f&lt;/i&gt; como parámetro y devuelve otra función que compone la función &lt;i&gt;f,&lt;/i&gt; &lt;i&gt;N&lt;/i&gt; veces consigo misma.&lt;/div&gt;&lt;div&gt;es decir&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function churchOne(f){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return function(x){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;return f(x);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function churchTwo(f){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return function(x){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;return f(f(x));&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function churchTree(f){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return function(x){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;return f(f(f(x)));&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sin embargo sería aburridisimo expresar los números de esa forma, por tanto define una funcion &lt;i&gt;Sucesor&lt;/i&gt; que es una función que recibe un número de Church &lt;i&gt;N&lt;/i&gt; como parámetro y devuelve el siguiente número de Church (&lt;i&gt;N+1&lt;/i&gt;)&lt;/div&gt;&lt;div&gt;El sucesor de Church se escribe de la siguiente forma &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function churchSucc (n) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return function (f) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;return function (x) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;return f(n(f)(x));&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;};&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Además tambien define el cero de Church como una función que recibe una función &lt;i&gt;f&lt;/i&gt; como parámetro y devuelve la función Identidad (caprichoso el cero) , de la forma&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function churchZero (f){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return I;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pero.... de que esta hablando Church, pues bien para que se den una idea, si &lt;i&gt;f(x)=x+1&lt;/i&gt; , entonces el calculo lambda se vuelve la aritmética común, de esta forma podemos probar el siguiente programa completo para ver los números de Church en toda su gloria&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function I (x) { &lt;/div&gt;&lt;div&gt;    return x; &lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;function churchZero (f) {&lt;/div&gt;&lt;div&gt;    return I;&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function churchSucc (n) {&lt;/div&gt;&lt;div&gt; return function (f) {&lt;/div&gt;&lt;div&gt;  return function (x) {&lt;/div&gt;&lt;div&gt;   return f(n(f)(x));&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt; };&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function f(x){ &lt;/div&gt;&lt;div&gt;   return x+1;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(f(0));//1&lt;/div&gt;&lt;div&gt;alert(I(f)(0)); //1&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(churchZero(f)(0)); //0&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var churchOne=churchSucc(churchZero);&lt;/div&gt;&lt;div&gt;alert(churchOne(f)(0));//1&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var churchTwo=churchSucc(churchOne);&lt;/div&gt;&lt;div&gt;alert(churchTwo(f)(0));//2&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(churchSucc(churchSucc(churchSucc(churchZero)))(f)(0));//3&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Entonces vemos que el mismo churchSucc es una función suceptible de ser utilizada con los mismos numeros de Church para hallar números de Church superiores&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert( churchTwo(churchSucc)(churchTwo)(f)(0) );//4&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Entonces vemos que se puede volver realmente muy interesante la composición sucesiva de una función.&lt;/div&gt;&lt;div&gt;Por ahora los dejos solamente con los números y volveremos luego con algunos operadores.&lt;/div&gt;&lt;div&gt;Si te cansaste de leer Church a lo largo del post, te dejo el resultado de la siguiente función&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;function f(x){ &lt;/div&gt;&lt;div&gt;   return x+'Church ';&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var churchTen =churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchSucc(churchZero))))))))));&lt;/div&gt;&lt;div&gt;alert( churchTen(f)(''));&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;//Church Church Church Church Church Church Church Church Church Church &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;jajajaa&lt;/div&gt;&lt;div&gt;que lo disfrutes!&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://uxul.wordpress.com/2009/03/02/generating-church-numbers-with-javascript/"&gt;Articulo fuente&lt;/a&gt; de la implementación Javascript (al que aprovechamos y le dimos una manito)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-6065044494155465038?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/6065044494155465038/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/04/1-2-3-todos-la-church.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6065044494155465038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6065044494155465038'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/04/1-2-3-todos-la-church.html' title='1, 2, 3..... TODOS A LA CHURCH!'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-2676935401765519102</id><published>2011-04-15T20:10:00.000-07:00</published><updated>2011-04-15T20:23:39.184-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='funciones'/><category scheme='http://www.blogger.com/atom/ns#' term='avanzado'/><category scheme='http://www.blogger.com/atom/ns#' term='Y combinator'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Sabes programar en javascript...Y?</title><content type='html'>&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span" &gt;"Puedo escribir las funciones menos tristes esta noche."&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;span class="Apple-style-span" &gt;picanteverde&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Despues de tanto tiempo sin traerles nada divertido al blog, he decidido volver porque por suerte ahora tengo un trabajo donde puedo aprender cosas nuevas para traer por aca.&lt;/div&gt;&lt;div&gt;Hoy vamos a hablar de Y combinator (me encantaría escribir este post en ingles pero lo voy a hacer en castellano para contribuir un poco a la poquisima cantidad de articulos (de buen javascript) en este idioma).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" &gt;Qué es el combinador Y?&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ademas de ser una &lt;a href="http://en.wikipedia.org/wiki/Y_Combinator"&gt;empresa de Capital de riesgo de inversión&lt;/a&gt;  y un operador matemático (por dios que estas leyendo) tambien conocido como &lt;a href="http://en.wikipedia.org/wiki/Fixed_point_combinator"&gt;Fixed Point Combinator&lt;/a&gt; &lt;/div&gt;&lt;div&gt;es uno de los artilugios más fascinantes de la ciencia de la computación y es muy simple de explicar (eso es mentira). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;El Combinador Y es una funcion de alto orden que calcula el punto fijo (fixed point) de otra funcion.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Si no entendiste nada vamos por partes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El punto fijo (fixed point) de una función f es un valor x tal que: f(x)=x&lt;/div&gt;&lt;div&gt;Por ejemplo &lt;i&gt;1&lt;/i&gt; y &lt;i&gt;0&lt;/i&gt; son puntos fijos de la función &lt;i&gt;cuadrado&lt;/i&gt;, debido a que si&lt;/div&gt;&lt;div&gt;&lt;i&gt;f(x)=x^2 &lt;/i&gt;entonces &lt;i&gt;1^2=1&lt;/i&gt; y &lt;i&gt;0^2=0&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;Ahora bien, eso es valido para funciones de primer orden (funciones en valores simples como enteros).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para una función &lt;b&gt;&lt;i&gt;f&lt;/i&gt;&lt;/b&gt; de alto orden, un punto fijo es otra función &lt;b&gt;&lt;i&gt;p&lt;/i&gt;&lt;/b&gt; de forma que &lt;b&gt;&lt;i&gt;f(p)=p&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;y un combinador de punto fijo (combinador Y), es OTRA función &lt;b&gt;&lt;i&gt;g&lt;/i&gt;&lt;/b&gt; que produce una función punto fijo &lt;b&gt;&lt;i&gt;p&lt;/i&gt;&lt;/b&gt; para cualquier funcion &lt;i style="font-weight: bold; "&gt;f &lt;/i&gt;de forma que:&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;p=g(f), f(p)=p&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;ó&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;i&gt;f(g(f))=g(f)&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ya se a esta altura te estas arrepintiendo de haberte puesto a leer algo que no parece tener nada que ver con javascript pero ahora vamos a escribirlo en javascript, no porque sea útil en si, disculpen mi obtusa visión pero aún no logro comprenderlo tanto como para encontrarle una funcionalidad, es por eso que decidí escribir este post (de la misma forma que el &lt;a href="http://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/"&gt;post que estoy leyedo&lt;/a&gt; ).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" &gt;Para qué sirve Y?&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Y es comúnmente usado para permitir recursión anónima en lenguajes donde no se puede asumir que esté soportada. &lt;/div&gt;&lt;div&gt;Veamos un ejemplo con una función para calcular el factorial de un numero de forma recursiva.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var factorial = function(x){&lt;/div&gt;&lt;div&gt;  return x == 0 ? 1 : x * factorial(x - 1);&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial(4)); //24&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;pero que pasaría si....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var factorial = function(x){&lt;/div&gt;&lt;div&gt;  return x == 0 ? 1 : x * factorial(x - 1);&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var fac=factorial;&lt;/div&gt;&lt;div&gt;factorial="nada";&lt;/div&gt;&lt;div&gt;alert(fac(4));&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Deja de funcionar debido a que factorial llamado desde dentro de la función no es más la función misma, sino otra cosa.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Antes que nada voy a aclarar que javascript si permite recursividad anónima usando callee&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var factorial = function(x){&lt;/div&gt;&lt;div&gt;  return x == 0 ? 1 : x * arguments.callee(x - 1);&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var fac=factorial;&lt;/div&gt;&lt;div&gt;factorial="nada";&lt;/div&gt;&lt;div&gt;alert(fac(4));&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Peeeero si no pudiese, necesitaríamos el combinador Y, vamos a encontrarlo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Supongamos que para evitar esto, pasamos una referencia de la función con la que debe realizar la recursividad, evitando así hacer cualquier tipo de referencia a alguna variable global.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var factorial = function(h, x){&lt;/div&gt;&lt;div&gt;  return x == 0 ? 1 : x * h(h, x - 1);&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;alert(factorial(factorial, 4));// 24&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pero podemos precompilar el primer parametro de la función y devolver una función que reciba solo un parametro, y escribirla de la siguiente manera&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var factorial = function(h){&lt;/div&gt;&lt;div&gt;  return function(x){&lt;/div&gt;&lt;div&gt;    return x == 0 ? 1 : x * h(h)(x - 1);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial(factorial)(4));&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Aquí yace la magia, &lt;i&gt;factorial&lt;/i&gt; recibe una referencia a si misma y devuelve una función recursiva sobre su propia referencia, de ahí que &lt;i&gt;[h(h)]&lt;/i&gt; devuelve una función recursiva sobre si misma. Por tanto debemos invocarla en la forma &lt;i&gt;[factorial(factorial)](4)&lt;/i&gt;, donde la función devuelta por &lt;i&gt;factorial(factorial)&lt;/i&gt; es la función recursiva.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hasta ahí todo bien, pero tenemos ese &lt;i&gt;h(h)(x) &lt;/i&gt;en la definición de la función, en lugar de un simple &lt;i&gt;q(x)&lt;/i&gt;, entonces podemos crear otra función de envoltorio que cree una referencia a &lt;i&gt;h(h)&lt;/i&gt;, es simplemente para poder llamarla en la forma &lt;i&gt;q(x)&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var factorial = function(h){&lt;/div&gt;&lt;div&gt;  return function(x){&lt;/div&gt;&lt;div&gt;    var f = function (q,x){&lt;/div&gt;&lt;div&gt;      return x == 0 ? 1 : x * q(x - 1);&lt;/div&gt;&lt;div&gt;    };&lt;/div&gt;&lt;div&gt;    return f(h(h), x);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial(factorial)(4));&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ahora en la función &lt;i&gt;f&lt;/i&gt; podemos realizar la misma precompilación del primer parametro que ya hicimos antes y obtener la siguiente función&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var factorial = function(h){&lt;/div&gt;&lt;div&gt;  return function(x){&lt;/div&gt;&lt;div&gt;    var f = function(q){&lt;/div&gt;&lt;div&gt;      return function(x){&lt;/div&gt;&lt;div&gt;        return x == 0 ? 1 : x * q (x - 1);&lt;/div&gt;&lt;div&gt;      };&lt;/div&gt;&lt;div&gt;    };&lt;/div&gt;&lt;div&gt;    return f(h(h))(x);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial(factorial)(4));&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;pero ahora, la función &lt;i&gt;f&lt;/i&gt; no posee ninguna referencia externa o global, asi que podemos sacarla afuera, y aún así funcionará.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var f = function(q){&lt;/div&gt;&lt;div&gt;  return function(x){&lt;/div&gt;&lt;div&gt;    return x == 0 ? 1 : x * q (x - 1);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var factorial = function (h){&lt;/div&gt;&lt;div&gt;  return function (x){&lt;/div&gt;&lt;div&gt;    return f(h(h))(x);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial(factorial)(4));&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ahora llegamos a que &lt;i&gt;f&lt;/i&gt; es nuestra función de la que queremos el punto fijo. el punto fijo es la función devuelta por &lt;i&gt;factorial(factorial)&lt;/i&gt;, entonces podemos escribir &lt;i&gt;Y()&lt;/i&gt; para que nos la devuelva de la siguiente manera.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var Y = function (f){&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  var g = function (h){&lt;/div&gt;&lt;div&gt;    return function(x){&lt;/div&gt;&lt;div&gt;      return f(h(h))(x);&lt;/div&gt;&lt;div&gt;    };&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  return g(g);&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var factorial = function (q){&lt;/div&gt;&lt;div&gt;  return function(x){&lt;/div&gt;&lt;div&gt;    return x == 0 ? 1 : x * q(x - 1);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var factorial_recursivo = Y(factorial);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial_recursivo(4));&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finalmente escrita en propósito general, quedaría&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;var Y = function(f){&lt;/div&gt;&lt;div&gt;  return (function (g) {&lt;/div&gt;&lt;div&gt;    return g(g);&lt;/div&gt;&lt;div&gt;  })(function(h) {&lt;/div&gt;&lt;div&gt;    return function(){&lt;/div&gt;&lt;div&gt;      return f(h(h)).apply(null,arguments);&lt;/div&gt;&lt;div&gt;    };&lt;/div&gt;&lt;div&gt;  });&lt;/div&gt;&lt;div&gt;};&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;//Y LISTO!!!! ahora podemos escribir factorial así&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;var factorial = Y(function(recurse){&lt;/div&gt;&lt;div&gt;  return function(x){&lt;/div&gt;&lt;div&gt;    return x==0 ? 1 : x * recurse(x - 1);&lt;/div&gt;&lt;div&gt;  };&lt;/div&gt;&lt;div&gt;});&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alert(factorial(4)); //24!!!!!!!!&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lo más frustrante acerca del combinador &lt;i&gt;Y&lt;/i&gt; es que una ves que lo derivaste, es imposible decir que hace, con solo mirar su código.&lt;/div&gt;&lt;div&gt;Si llegaste hasta aquí, sin marearte, FELICITACIONES!!!!!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-2676935401765519102?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/2676935401765519102/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2011/04/sabes-programar-en-javascripty.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2676935401765519102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2676935401765519102'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2011/04/sabes-programar-en-javascripty.html' title='Sabes programar en javascript...Y?'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8650176823272158308</id><published>2009-07-01T10:46:00.000-07:00</published><updated>2009-07-01T11:01:18.571-07:00</updated><title type='text'>Adelantandose a los thread en Javascript</title><content type='html'>Como muchos de ustedes saben los threads son una feature que esta llegando a Javascript, obvio cada implementación tendrá sus tiempos para lograrlo pero ya en firefox 3.5 podemos disfrutar de los &lt;a href="https://developer.mozilla.org/En/Using_DOM_workers"&gt;web workers&lt;/a&gt; pero lo verdaderamente sorprendente de esto es que tambien podemos encontrar implementaciones en javascript de threads para javascript, algo sorprendente sin duda.&lt;br /&gt;veamos las librerias que hay:&lt;br /&gt;&lt;a href="http://www.infoq.com/articles/js_multithread"&gt;jsthread&lt;/a&gt; es la primer implementación que conocí y aunque no la utilicé aún, parece bastante poco practica ya que sugiere que convierten el codigo de la funcion en un string y la compila nuevamente de manera que pueda ser interrumpida y reanudada intercambiando sus entornos de ejecución.&lt;br /&gt;Lamentablemente no he tenido tiempo para probar ninguna de estas librerias pero en cuanto lo tenga vendré con algunos ejemplos para que los puedan probar en casa.&lt;br /&gt;&lt;br /&gt;les dejo otros links utiles de lectura recomendada&lt;br /&gt;&lt;a href="http://ajaxian.com/archives/javascript-threading-and-continuations"&gt;ajaxian&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blog.monstuff.com/archives/000315.html"&gt;como implementar threas en js?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Saludos&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8650176823272158308?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8650176823272158308/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/adelantandose-los-thread-en-javascript.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8650176823272158308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8650176823272158308'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/adelantandose-los-thread-en-javascript.html' title='Adelantandose a los thread en Javascript'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-2826219766325921637</id><published>2009-07-01T10:24:00.000-07:00</published><updated>2009-07-01T10:27:25.569-07:00</updated><title type='text'>Como recorrer un array</title><content type='html'>Existen mas de una forma de recorrer un array y las podemos encontrar a todas juntas en:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ajaxian.com/archives/how-many-ways-can-you-iterate-over-an-array-in-javascript"&gt;http://ajaxian.com/archives/how-many-ways-can-you-iterate-over-an-array-in-javascript&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-2826219766325921637?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/2826219766325921637/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/como-recorrer-un-array.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2826219766325921637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2826219766325921637'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/como-recorrer-un-array.html' title='Como recorrer un array'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-2907315235809870058</id><published>2009-07-01T10:01:00.000-07:00</published><updated>2009-07-01T10:16:54.015-07:00</updated><title type='text'>como hacer Bien un For</title><content type='html'>Y pensar que puse javascriptexperts en el nombre del blog porque creí que sabia suficiente de javascript pero siempre hay alguien que sorprende.&lt;br /&gt;Generalmente la peor manera de hacer un for es&lt;br /&gt;&lt;br /&gt;for (var i=0; i&lt;arr.length; i++){&lt;br /&gt;     alert(arr[i]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;porque?, debido a que por cada iteración debemos ir a buscar el valor de la variable length, dentro de arr, con lo cual desperdiciamos tiempo. en su lugar si hiciesemos&lt;br /&gt;&lt;br /&gt;for(var i= arr.length;i&gt;=0;i--){&lt;br /&gt;    alert(arr[i]);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;de esta forma, tambien recorremos el array arr solo que esta vez por cada iteracion simplemente comaramos i con 0, y no con el valor de una variable que pudo haber cambiado.&lt;br /&gt;podemos ver la fuente en&lt;br /&gt;&lt;a href="http://www.anieto2k.com/2009/05/28/for-reverso-para-grandes-interaciones-en-javascript/"&gt;http://www.anieto2k.com/2009/05/28/for-reverso-para-grandes-interaciones-en-javascript/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-2907315235809870058?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/2907315235809870058/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/como-hacer-bien-un-for.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2907315235809870058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2907315235809870058'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/como-hacer-bien-un-for.html' title='como hacer Bien un For'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-4776814184954728975</id><published>2009-07-01T09:53:00.001-07:00</published><updated>2009-07-01T09:57:34.044-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='avanzado'/><title type='text'>Ventanas gelatinosas?</title><content type='html'>Despues de un largo tiempo si post vuelvo con una seguidilla importante de cosas que debemos mirar para saber un poco mas de javascript. como por ejemplo este link con ventanas gelatinosas.&lt;br /&gt;(script que no puedo ver en funcionamiento ya que en el edificio donde trabajo tenemos internet censurada por &lt;a href="http://en.wikipedia.org/wiki/Websense"&gt;websense &lt;/a&gt;el cual marco este sitio, como un sitio de video juegos)&lt;br /&gt;el link es&lt;br /&gt;&lt;a href="http://www.turleando.com.ar/2009/06/ventanas-gelatinosas-con-javascript-y-css-transforms/"&gt;http://www.turleando.com.ar/2009/06/ventanas-gelatinosas-con-javascript-y-css-transforms/&lt;/a&gt;&lt;br /&gt;y realmente les recomiendo que lo visiten y me cuenten que les parece.&lt;br /&gt;Saludos&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-4776814184954728975?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/4776814184954728975/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/ventanas-gelatinosas.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4776814184954728975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4776814184954728975'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/07/ventanas-gelatinosas.html' title='Ventanas gelatinosas?'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8989923090419836662</id><published>2009-06-19T08:53:00.000-07:00</published><updated>2009-06-19T08:54:44.649-07:00</updated><title type='text'>lo que tengo que decir sobre Internet Explorer</title><content type='html'>esto es todo lo que tengo que decir sobre Internet Explorer 8&lt;br /&gt;&lt;a href="http://www.anieto2k.com/2009/01/13/el-motivo-por-el-que-internet-explorer-es-el-mejor-navegador/"&gt;aqui&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8989923090419836662?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8989923090419836662/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/lo-que-tengo-que-decir-sobre-internet.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8989923090419836662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8989923090419836662'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/lo-que-tengo-que-decir-sobre-internet.html' title='lo que tengo que decir sobre Internet Explorer'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-5442525472684485651</id><published>2009-06-04T06:30:00.000-07:00</published><updated>2009-06-09T05:22:46.982-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='principiante'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><title type='text'>Funciones lambda o anonimas</title><content type='html'>Ahora que ya comprendemos el concepto de closures, podremos apreciar con mayor amplitud el verdadero poder de las funciones lambda o anonimas. Pero primero lo primero, porque se llaman lambda?.&lt;br /&gt;Las funciones anonimas en programación deben el nombre de lambda, a la teoría matemática del &lt;a href="http://es.wikipedia.org/wiki/C%C3%A1lculo_lambda"&gt;Calculo Lambda&lt;/a&gt; inventada por &lt;a href="http://es.wikipedia.org/wiki/Alonzo_Church"&gt;Alonzo Church&lt;/a&gt; y &lt;a href="http://es.wikipedia.org/wiki/Stephen_Kleene"&gt;Stephen Kleen&lt;/a&gt; (que no es el creador de la botella, ese es &lt;a href="http://es.wikipedia.org/wiki/Botella_de_Klein"&gt;Klein&lt;/a&gt;) Teoría que sin duda esta fuera del alcance del entendimiento del humano medio, asi que si la comprendes, bien por ti.&lt;br /&gt;Bien, ahora para que son utiles las funciones lambda?, de que sirve no ponerle nombre a una función?. Las utilidaded de las funciones lambda son casi infinitas pero intentaré mostrarles aquí las que yo considero son las más importantes.&lt;br /&gt;Las posibilidad de usar funciones anonimas va de la mano con otros conceptos importantes de Javascript, como :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Todo es un objeto: &lt;/span&gt;(incluidas las funciones), esto me permite asignar funciones a variables, y hacer referencia a ellas utilizando la variable, además me permite pasar funciones como parametros a otras funciones, y obtener funciones como resultados de la ejecución de una función.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Closures:&lt;/span&gt; Gracias a las Closures tenemos la ventaja de poder enlazar nuestras funciones con variables de otros entornos de ejecución, algo que veremos es más que util a la hora de trabajar con interfaces web.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Objetos dinamicos:&lt;/span&gt;  A la hora de modificar el comportamiento de un objeto en particular, podemos definir una funcion y asignarla inmediatamente a un método de un objeto, sobreescribiendo su comportamiento inicial, o extendiendo su interfaz para agregar comportamiento nuevo.&lt;/li&gt;&lt;/ul&gt;bueno ahora un poco de codigo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//funcion lambda asignada a una variable&lt;br /&gt;var sumar = function (a,b){&lt;br /&gt;  return a+b;&lt;br /&gt;}&lt;br /&gt;alert(sumar(1,2));&lt;br /&gt;// es lo mismo que decir&lt;br /&gt;function sumar (a,b){&lt;br /&gt;  return a+b;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ahora supongamos que tenemos una funcion que busca el más grande de todos los numeros en un array&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var masGrande = function (arr){&lt;br /&gt;  var mayor=0;&lt;br /&gt;  var len = arr.length;&lt;br /&gt;  for(var i=0;i&lt;&gt;mayor){&lt;br /&gt;          mayor=arr[i];&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;  return mayor;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var intArr = [1,2,3,4,5,6,7,8];&lt;br /&gt;alert(masGrande(intArr));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ahora que sucede si queremos comparar por ejemplo un array de objetos personas, donde cada persona tiene un miembro edad con el valor de su edad. veamos como reescribiriamos la función&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var masGrande = function (arrP){&lt;br /&gt;  var mayor=0;&lt;br /&gt;  var len = arr.length;&lt;br /&gt;  for(var i=0;i&lt;&gt;mayor.edad){&lt;br /&gt;          mayor=arr[i];&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;  return mayor;&lt;br /&gt;}&lt;br /&gt;var personasArr = [{edad:2},{edad:2},{edad:2},{edad:2},{edad:2},{edad:2},{edad:2}];&lt;br /&gt;alert(masGrande(personasArr));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pero este codigo es solamente util para encontrar la mayor "persona", y no sirve para ningun otro tipo de objeto (aunque a decir verdad si los objetos del array poseen un miembro edad es suficiente).&lt;br /&gt;Como podríamos escribir un algoritmo que aisle el comportamiento de buscar un mayor sin importar de los objetos que estemos comparando.&lt;br /&gt;Bueno gracias a las funciones anonimas podemos.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//si analizamos los ejemplos anteriores podemos ver que lo unico que&lt;br /&gt;//cambia es el momento de comparar si un objeto es mayor o no&lt;br /&gt;//entonces que sucede si&lt;br /&gt;var masGrande = function (arr, esMayor){&lt;br /&gt;//    en el parametro comparar recibiremos una funcion que compare dos objetos y nos&lt;br /&gt;//    pueda decir cual es el mayor.&lt;br /&gt;  var mayor=0;&lt;br /&gt;  var len = arr.length;&lt;br /&gt;  for(var i=0;i&lt; mayor="arr[i];" personasarr =" [{edad:2},{edad:2},{edad:2},{edad:2},{edad:2},{edad:2},{edad:2}];"&gt;b.edad){&lt;br /&gt;      return true;&lt;br /&gt;  }else{&lt;br /&gt;      return false;&lt;br /&gt;  }&lt;br /&gt;}));&lt;br /&gt;&lt;br /&gt;//podemos buscar el mayor número&lt;br /&gt;var intArr = [1,2,3,4,5,6,7,8];&lt;br /&gt;alert(masGrande(intArr,function(a,b){&lt;br /&gt;  if(a&gt;b){&lt;br /&gt;      return true;&lt;br /&gt;  }else{&lt;br /&gt;      return false;&lt;br /&gt;  }&lt;br /&gt;}));&lt;br /&gt;&lt;br /&gt;//podemos buscar el mayor de objetos con estructuras complicadas&lt;br /&gt;var objArr = [{edad:20,fuerza:40},{edad:30,fuerza:50},{edad:10,fuerza:23},{edad:21,fuerza:40}];&lt;br /&gt;alert(masGrande(objArr,function(a,b){&lt;br /&gt;  if((50-a.edad)*a.fuerza&gt;(50-b.edad)*b.fuerza){&lt;br /&gt;      return true;&lt;br /&gt;  }else{&lt;br /&gt;      return false;&lt;br /&gt;  }&lt;br /&gt;}));&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Como vemos hemos logrado aislar el comportamiento de buscar un mayor sin importar los objetos que estemos comparando.&lt;br /&gt;&lt;br /&gt;Ahora veamos un ejemplo simple para modificar el comportamiento de un objeto&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var perro=function(){};&lt;br /&gt;&lt;br /&gt;perro.prototype={&lt;br /&gt;comer: function(){&lt;br /&gt;      alert('comiendo con el hocico');&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var persona = new perro;&lt;br /&gt;persona.comer=function(){&lt;br /&gt;  alert('comiendo con la boca');&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;es muy sencillo entender la utilidad de este tipo de estructuras luego de observar estos ejemplos&lt;br /&gt;(los ejemplos no han sido probado, si al probarlos encontrases algun error por favor comunicamelo e intenta encontrar la solucion)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-5442525472684485651?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/5442525472684485651/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/funciones-lambda-o-anonimas.html#comment-form' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5442525472684485651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5442525472684485651'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/funciones-lambda-o-anonimas.html' title='Funciones lambda o anonimas'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7762402458485200705</id><published>2009-06-04T06:26:00.000-07:00</published><updated>2009-06-04T06:28:43.496-07:00</updated><title type='text'>Closures</title><content type='html'>Las closures o cerraduras son un tema bastante explicado en javascript, el problema es que es tan confuso que aún cuando entendamos el concepto dificilmente aprovechamos su potencial en nuestros programas.&lt;br /&gt;Veamos la defininición.&lt;br /&gt;Una Closure es una función que es evaluada en un entorno conteniendo una o más variables dependientes de otro entorno.&lt;br /&gt;Como vemos la definición no hace más que contribuir a la confusión.&lt;br /&gt;Veamoslo así.&lt;br /&gt;En Javascript podemos definir una función en cualquier momento, inclusive dentro de la definición de otra función.&lt;br /&gt;veamos una funcion para encontrar todos los numeros pares entre 2 numeros.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function numerosPares(Desde,Hasta){&lt;br /&gt;   function esPar(Num){&lt;br /&gt;       if(Num%2==0){&lt;br /&gt;           return true;&lt;br /&gt;       }else{&lt;br /&gt;           return false;&lt;br /&gt;       }&lt;br /&gt;       //o, lo que es lo mismo&lt;br /&gt;       //return !Num%2;&lt;br /&gt;   }&lt;br /&gt;   var pares = [];&lt;br /&gt;   for (var i=Desde;i&lt; Hasta;i++){        &lt;br /&gt;        if(esPar(i)){&lt;br /&gt;           pares.push(i);&lt;br /&gt;        }&lt;br /&gt;   }&lt;br /&gt;   return pares;&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;allí podemos ver como declaramos una función dentro de otra.&lt;br /&gt;Ahora que sabemos esto es mucho más facil comprender que es una closure&lt;br /&gt;vamos a crear una función crearFuncion que, al ejecutarla, devolverá una nueva función sumar que al ser ejecutada actualizará una variable i que fue declarada dentro de la función crearFuncion.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;////Closures&lt;br /&gt;function crearFuncion(){&lt;br /&gt;   var i=0;&lt;br /&gt;   var sumar = function(){&lt;br /&gt;       i=i+1;&lt;br /&gt;       return i;&lt;br /&gt;   };&lt;br /&gt;   return sumar;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var fsumar = crearFuncion();&lt;br /&gt;&lt;br /&gt;alert(fsumar());&lt;br /&gt;alert(fsumar());&lt;br /&gt;alert(fsumar());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ahora podemos ver como al haber declarado la funcion sumar dentro de la función crarFuncion, la función sumar tiene acceso a todas las variables a las que tenía acceso la función crearFuncion, aún despues de que crearFunción finalizó su ejecución. Entonces decimos sumar es una closure ya que poseé acceso a todas las variables de la función donde fué declarada.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7762402458485200705?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7762402458485200705/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/closures.html#comment-form' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7762402458485200705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7762402458485200705'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/closures.html' title='Closures'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7284581816231788123</id><published>2009-06-04T06:24:00.000-07:00</published><updated>2009-06-04T06:26:38.271-07:00</updated><title type='text'>Lenguaje dinámico</title><content type='html'>Bien, &lt;span style="font-weight: bold;"&gt;javascript&lt;/span&gt; es un lenguaje dinámico por que poseé objetos dinámicos. Y... qué es un objeto dinámico?.&lt;br /&gt;Un objeto dinámico es un objeto que puede cambiar la definición de sus miembros en tiempo de ejecución.&lt;br /&gt;cual es la diferencia con un objeto común?&lt;br /&gt;En un lenguaje orientado a objeto y con clases, los objetos son tipicamente estaticos, con lo cual no podemos por ejemplo cambiar la definición de un método en tiempo de ejecución. En cambio en un objeto dinámico si podemos hacer esto.&lt;br /&gt;Es importante comprender que esta caracteristica de javascript afecta profundamente a nuestra forma de programar, ya que nunca podremos estar seguros, a priorí, sobre la definición de los miembros de un objeto que recibamos como parámetro por ejemplo.&lt;br /&gt;Veamos un poco de como utilizar esto en el código.&lt;br /&gt;Supongamos que creamos un objeto iluminador, que posea un método prender y un miembro obj, al ejecutar el método prender, el objeto iluminador se encarga de setear el color de fondo de su objeto obj, a blanco.&lt;br /&gt;(recuerda que puedes ejecutar este código pegandolo en el cuadro de texto en la parte superior derecha de este blog)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/// objetos dinamicos&lt;br /&gt;//definimos el objeto iluminador&lt;br /&gt;var iluminador = function (){&lt;br /&gt;this.obj=null;&lt;br /&gt;}&lt;br /&gt;//definimos el método prender, dentro del prototipo de iluminador&lt;br /&gt;iluminador.prototype.prender = function(){&lt;br /&gt;this.obj.style.backgroundColor = 'white';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Creamos una instancia de iluminador, en la variable i&lt;br /&gt;var i = new iluminador();&lt;br /&gt;&lt;br /&gt;//obtenemos una referencia a algun objeto de la página&lt;br /&gt;//en este caso el cuadro de cabecera&lt;br /&gt;var head = document.getElementById('header-wrapper');&lt;br /&gt;&lt;br /&gt;//este es nuestro primer caso de objeto dinamico&lt;br /&gt;// hasta ahora no habiamos definido el miembro obj para nuestra instancia i&lt;br /&gt;// ahora colocamos la referencia head en el miembro obj.&lt;br /&gt;i.obj =head;&lt;br /&gt;//podemos ver la definicion de prender&lt;br /&gt;alert(i.prender);&lt;br /&gt;//iluminamos el objeto obj en este caso head&lt;br /&gt;i.prender();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//OBJETO DINÁMICO&lt;br /&gt;//en javascript podemos redefinir un miembro, en este caso un método, en tiempo de&lt;br /&gt;//ejecuccion y de esta forma modificar el comportamiento.&lt;br /&gt;i.prender=function(){&lt;br /&gt;this.obj.style.border = '5px solid green';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//ahora el método prender, en lugar de iluminar el objeto obj,&lt;br /&gt;//se encarga de establecer el borde del objeto a 5 pixeles en color verde.&lt;br /&gt;i.prender();&lt;br /&gt;&lt;br /&gt;//es importante comprender que el objeto que cambio es el objeto i,&lt;br /&gt;//y no el objeto iluminador, ya que si creamos una nueva instancia del&lt;br /&gt;//objeto iluminador, dentro de la variable i2&lt;br /&gt;var i2 = new iluminador();&lt;br /&gt;i2.obj =head;&lt;br /&gt;//podemos ver que la definicion del miembro prender, continua siendo la del&lt;br /&gt;//objeto iluminador. la razón de esto será mucho más clara cuando&lt;br /&gt;//veamos herencia prototipal&lt;br /&gt;alert(i2.prender);&lt;br /&gt;i2.prender();&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7284581816231788123?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7284581816231788123/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/lenguaje-dinamico.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7284581816231788123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7284581816231788123'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/06/lenguaje-dinamico.html' title='Lenguaje dinámico'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-4221701261484638031</id><published>2009-05-26T04:35:00.000-07:00</published><updated>2009-06-04T06:29:10.802-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='principiante'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><title type='text'>Javascript, Objetos Dinámicos, Closures, Funciones Lambda, Herencia Prototypal</title><content type='html'>Bueno despues de tanto tiempo recien logro hacerme un espacio para charlar sobre &lt;span style="font-weight: bold;"&gt;javascript&lt;/span&gt; nuevamente con ustedes. Hoy vamos a ver el porqué? de todos estos conceptos nuevos que vienen incluidos en javascript, y como poder utilizarlos en proyectos de la vida real. Por ejemplo, vamos a ver la diferencia entre: saber que es una función lambda o anonima, y utilizarlas para lograr un diseño de objeto avanzado.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Introducción&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Primero lo primero, &lt;span style="font-weight: bold;"&gt;Javascript &lt;/span&gt;es un lenguaje dinámico orientado a objetos con soporte de funciones anonimas, y closures o cerraduras. Precisamente definir a javascript de esta manera genera tipicamente más confusión que no conocer las caracteristicas de javascript, entonces voy a intentar explicar una a una estas caracterisitas con ejemplos concretos y faciles de comprende, que resalten la esencia de cada caracteristica del lenguaje y nos permitan ver más allá sus posibilidades de utilización.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Caracteristicas&lt;/span&gt;&lt;br /&gt;Mucho hemos oido hablar sobre las poderosas caracteristicas de javascript, por ejemplo del soporte de funciones labda y closures. Pero realmente cuales son las verdaderas caracteristicas de javascript?. Bueno a continuación podemos ver un listado no exaustivo de las caracteristicas principales de &lt;span style="font-weight: bold;"&gt;javascript&lt;/span&gt;.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Lenguaje dinámico: &lt;/span&gt;Se dice que &lt;span style="font-weight: bold;"&gt;Javascript &lt;/span&gt;es un lenguaje dinámico ya que poseé objetos dinamicos, estos son objetos que pueden variar su definición y comportamiento en tiempo de ejecución. Todos los objetos en &lt;span style="font-weight: bold;"&gt;javascript &lt;/span&gt;son dinámicos.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Closures: &lt;/span&gt;Las closures o cerraduras en javascript son una estructura del lenguaje que no poseé una sintaxis facil de explicar, pero que básicamente nos permite acceder a variables que fueron declaradas fuera de la función que estemos escribiendo, aún despues de que la funcion mayor hubiese terminado su ejecución.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Funciones lambda o anonimas: Javascript &lt;/span&gt;nos permite crear funciones sin nombre (anonimas) y poder asignarlas a una variable, ya que las funciones tambien son un objetos. Por esta razón podemos pasar funciones como parametros a otras funciones, e inclusive podes devolver funciones como resultado de una función.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Herencia Prototipal: &lt;/span&gt;la herencia prototipal es uno de los aspectos más discutidos de &lt;span style="font-weight: bold;"&gt;javascript&lt;/span&gt;, y se basa en el hecho de que cada objeto en &lt;span style="font-weight: bold;"&gt;javascript &lt;/span&gt;(y en &lt;span style="font-weight: bold;"&gt;javascript &lt;/span&gt;todo es un objeto) posee un prototipo, como miembro de si mismo. Por lo tanto, todo objeto(A) que se cree a partir de un objeto(B), heredará todos los miembros del prototipo de ese objeto(B). Finalemente si se solicita un miembro m sobre un objeto determinado y este objeto no poseé una definición de su miembro m, se le solicitará ese miembro m a su prototipo, el cual es común a todos los objetos de ese tipo.&lt;/li&gt;&lt;/ul&gt;Como podemos ver, citamos 4 caracteristicas de &lt;span style="font-weight: bold;"&gt;javascript&lt;/span&gt;, expusimos de manera precisa su definición pero no ayudamos a su comprensión, a continuación intentaré explicar en profundidad las nociones de programación dentro de cada una de ellas.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-4221701261484638031?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/4221701261484638031/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/05/javascript-objetos-dinamicos-closures.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4221701261484638031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4221701261484638031'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/05/javascript-objetos-dinamicos-closures.html' title='Javascript, Objetos Dinámicos, Closures, Funciones Lambda, Herencia Prototypal'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-6588214533190531767</id><published>2009-04-20T22:14:00.000-07:00</published><updated>2009-04-20T22:40:28.496-07:00</updated><title type='text'>Jugando a ser Dios (haciendo un DSL)</title><content type='html'>Como vimos &lt;a href="http://javascriptexperts.blogspot.com/2009/03/metaprogramacion-o-dsl-con-javascript.html"&gt;antes&lt;/a&gt; no es muy dificil crear meta lenguajes o lenguajes de dominio especificos con Javascript. Pero como no se me habia ocurrido una aplicación especifica, deje pasar el hecho de no mostrar un DSL en concreto.&lt;br /&gt;Por suerte hace unos dias, en el trabajo, tuve la necesidad de realizar pequeñas o simple consultas algo parecidas a un SQL muy básico sobre algunas Arrays Javascript, entonces recordé mi post sobre DSL y decidí implementar algunas funcionalidades de javascript para que puedan ver un DSL en funcionamiento. aquí les va&lt;br /&gt;(si yo se que el código es largo pero lo voy a comentar bien asi se comprende)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//arrSQL.js&lt;br /&gt;var arrSQL =(function(){   //usamos una funcion para tener funciones privada&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//private constructor&lt;br /&gt; function _arrSQL(args){&lt;br /&gt;  this.sel=[];&lt;br /&gt;  this.from=args[0];&lt;br /&gt;  this.wh=[];&lt;br /&gt;  this.arrayResp=false;&lt;br /&gt;  return this;&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt; _arrSQL.prototype = {&lt;br /&gt;  where:function (crit){&lt;br /&gt;   this.wh.push(crit);&lt;br /&gt;   return this;&lt;br /&gt;  },&lt;br /&gt;  select:function(field){&lt;br /&gt;   if(arguments.length===1){&lt;br /&gt;    this.sel.push(field);&lt;br /&gt;   }else{&lt;br /&gt;    for(var i=0; i&lt;arguments.length;i++){ dist="true;" newo="{};" var="" f="" in="" return="" length="==0){"&gt;0){&lt;br /&gt;    var ret=true;&lt;br /&gt;    for(var c in this.wh){&lt;br /&gt;     var criterio = this.wh[c];&lt;br /&gt;     switch(criterio[1]){&lt;br /&gt;      case '=':&lt;br /&gt;       if (o[criterio[0]]!==criterio[2]){&lt;br /&gt;        ret =  false;&lt;br /&gt;       }&lt;br /&gt;       break;&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;    return ret;&lt;br /&gt;   }else{&lt;br /&gt;    return true;&lt;br /&gt;   }&lt;br /&gt;  },&lt;br /&gt;  distinctCheck:function(o){&lt;br /&gt;   if(this.dist){&lt;br /&gt;    var ret = false;&lt;br /&gt;    this.dist.returnRoot();&lt;br /&gt;    for (var name in this.sel){&lt;br /&gt;     if(this.dist.nav(o[this.sel[name]]) ){&lt;br /&gt;      ret = ret || false;&lt;br /&gt;     }else{&lt;br /&gt;      this.dist.add(o[this.sel[name]]);&lt;br /&gt;      this.dist.nav(o[this.sel[name]]);&lt;br /&gt;      ret = ret||true;&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;    return ret;&lt;br /&gt;   }else{&lt;br /&gt;    return true;&lt;br /&gt;   }&lt;br /&gt;  },&lt;br /&gt;  ret:function (){&lt;br /&gt;   var retu = [];&lt;br /&gt;   if(this.dist){&lt;br /&gt;    this.dist = new this.distCache();&lt;br /&gt;   }&lt;br /&gt;   for(var i=0;i &lt; distcache=" function(){" root="{};" curr="this.root;" prototype="{" curr =" this.curr[name];" curr =" this.root;"&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;JAJAJA bueno disculpen mi ausencia de comentarios pero me tengo que ir a dormir, pueden pedir explicaciones por los comentarios.&lt;br /&gt;Aqui tienen un pequeño html para poder probarlo&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var arr = [{"titulo":"Titulo1",&lt;br /&gt;            "nombre":"Nombre1",&lt;br /&gt;            "apellido":"Apellido1",&lt;br /&gt;            "descripcion":"Descripcion1"},&lt;br /&gt;            {"titulo":"Titulo1",&lt;br /&gt;            "nombre":"Nombre2",&lt;br /&gt;            "apellido":"Apellido2",&lt;br /&gt;            "descripcion":"Descripcion2"},&lt;br /&gt;            {"titulo":"Titulo1",&lt;br /&gt;            "nombre":"Nombre3",&lt;br /&gt;            "apellido":"Apellido3",&lt;br /&gt;            "descripcion":"Descripcion3"},&lt;br /&gt;            {"titulo":"Titulo1",&lt;br /&gt;            "nombre":"Nombre4",&lt;br /&gt;            "apellido":"Apellido4",&lt;br /&gt;            "descripcion":"Descripcion4"}];&lt;br /&gt;//alert(arr);&lt;br /&gt;alert(arrSQL(arr).select('nombre','apellido').distinct().where(['titulo','=','Titulo1']).ret());&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-6588214533190531767?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/6588214533190531767/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/04/jugando-ser-dios-haciendo-un-dsl.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6588214533190531767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6588214533190531767'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/04/jugando-ser-dios-haciendo-un-dsl.html' title='Jugando a ser Dios (haciendo un DSL)'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8133605699999237502</id><published>2009-04-15T07:52:00.000-07:00</published><updated>2009-04-15T07:57:44.596-07:00</updated><title type='text'>Google Map-Reduce</title><content type='html'>Bueno vamos a ir un poco al futuro y empecemos a hablar de Grid computing que es muy distinto de cloud computing&lt;br /&gt;&lt;br /&gt;Cloud Computing: la capacidad de procesamiento de una aplicación, no reside en el cliente, sino en la estructura de servidores.&lt;br /&gt;&lt;br /&gt;Grid Computing: la capacidad de procesamiento se distribuye en una gran cantidad de nodos, cada nodo procesa una pequeña porción de los datos.&lt;br /&gt;&lt;br /&gt;es complicado pero piensen asi&lt;br /&gt;Cloud Computing puede funcionar sobre Grid Compupting&lt;br /&gt;&lt;br /&gt;más allá de todo esto Google a liderado el mercado explicando su teoría &lt;a href="http://en.wikipedia.org/wiki/MapReduce"&gt;Map Reduce&lt;/a&gt;&lt;br /&gt;y ahora podemos ver los primeros avances en implementar estas tecnologías sobre javascript.&lt;br /&gt;Porque?&lt;br /&gt;porque javascript es el lenguaje más popular del mundo. practicamente todas las PC tienen uno o más interpretes de javascript instalados.&lt;br /&gt;De esta forma podríamos distribuir el procesamiento de nuestro set de datos a lo largo de millones de nodos, tantos como browsers seamos capaces de encontrar.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.igvita.com/2009/03/03/collaborative-map-reduce-in-the-browser/"&gt;http://www.igvita.com/2009/03/03/collaborative-map-reduce-in-the-browser/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8133605699999237502?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8133605699999237502/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/04/google-map-reduce.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8133605699999237502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8133605699999237502'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/04/google-map-reduce.html' title='Google Map-Reduce'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-126145511492692692</id><published>2009-03-30T18:04:00.000-07:00</published><updated>2009-03-30T20:09:37.190-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Douglas Crockford'/><category scheme='http://www.blogger.com/atom/ns#' term='textos'/><title type='text'>JavaScript: El Lennguaje de Programación Más Malentendido del Mundo</title><content type='html'>(Aquí les dejo traducido, el &lt;a href="http://javascript.crockford.com/javascript.html"&gt;primer texto&lt;/a&gt; que leí de &lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt;, y con el que me introduje en el interesantisimo mundo de javascript)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://javascript.crockford.com/"&gt;Javascript&lt;/a&gt; tambien conocido como: Mocha, LiveScript, JScript, ECMAScript es uno de los lenguajes de programación más populares del mundo. Virtualmente todo computador personal en el mundo tiene, al menos, ún interprete de JavaScript instalado en él, y en uso activo. La popularidad de JavaScript se debe enteramente a su rol como lenguaje de scripting de la WWW.&lt;br /&gt;A pesar de su popularidad, solo algunos saben que JavaScript es un muy buen lenguaje de programación dinámico, orientado a objetos, de proposito general. Cómo puede ser esto un secreto? Porqué este lenguaje es tan malentendido?&lt;br /&gt;&lt;br /&gt;El Nombre&lt;br /&gt;&lt;br /&gt;El prefijo &lt;span style="font-weight: bold;"&gt;Java&lt;/span&gt; sugiere que JavaScript está, de alguna manera, relacionado a Java, que es un sub conjunto o una version menos poderosa de Java. Resulta que el nombre fué intencionalmente seleccionado para crear confusión, y de la confusión viene el malentendimiento. JavaScript no es Java interpretado. Java es Java interpretado. JavaScript es un lenguaje diferente.&lt;br /&gt;&lt;br /&gt;JavaScript tiene una similitud sintáctica con Java, tanto como Java la tiene con C. Pero no es un sub conjunto de Java, tanto como Java no es un sub conjunto de C. Es mejor que Java en la aplicación para la que Java (oak) fue creado.&lt;br /&gt;&lt;br /&gt;JavaScript no fué desarrollado en Sun Microsystems, el hogar de Java. JavaScript fué desarrollado en Netscape. Fue originalmente llamado LiveScript. Pero el nombre no era lo suficientemente confuso.&lt;br /&gt;&lt;br /&gt;el sufijo &lt;span style="font-weight: bold;"&gt;Script&lt;/span&gt; sugiere que no es un lenguaje de programación real, que un lenguaje de scripting es más que un lenguaje de programación. Pero en realidad es una cuestión de especialización. Comparado con C Javascript tiende al performance para poder expresivo y dinaminsmio.&lt;br /&gt;&lt;br /&gt;Lisp vestido de C&lt;br /&gt;La sintaxis parecida a C, incluyendo las llaves y la manca sentencia for, lo hacen parecer un oridinario lenguaje de programación procedural. Esto está malinterpretado, porque JavaScript tiene más en común con lenguajes funcionales, como &lt;a href="http://javascript.crockford.com/little.html"&gt;Lisp o Scheme&lt;/a&gt;, que con C o Java. Tiene arreglos en vez de listas y objetos en lugar de listas de propiedades. Las funciones son de primera clase (first class).  Tiene cerraduras (closures). Tiene lambdas sin tener que balancear todos esos parentecis.&lt;br /&gt;&lt;br /&gt;Encasillamiento (Typecasting)&lt;br /&gt;JavaScript fué diseñado para correr en Netscape Navigator. Su éxito allí lo llevó a convertirse en un equipamiento estandar de virtualmente todos los navegadores web. Esto lo llevó al encasillamiento. JavaScript es el &lt;a href="http://www.amazon.com/exec/obidos/ASIN/B000KWZ7JC/wrrrldwideweb"&gt;George Reeves&lt;/a&gt; de los lenguajes de programación. JavaScript se ha adaptado bien a una gran cantidad de aplicaciones no relacionadas con la web.&lt;br /&gt;&lt;br /&gt;Objetivo Cambiante&lt;br /&gt;La primer versión de JavaScript fué muy debil. Carecía de manejo de excepciones, inner functions, y herencia. En su forma actual, es ahora un completo lenguaje de programación orientado a objetos. Pero muchas de las opiniones sobre el lenguaje estan basadas en sus comienzos  inmaduros.&lt;br /&gt;&lt;br /&gt;El comite ECMA, que tiene el control sobre el lenguaje, esta desarrollando extensiones que, aunque bien intencionadas, van a agrabar uno de los problemas más grandes del lenguaje: Ya existen actualmente demasiadas versiones. Esto crea confusión.&lt;br /&gt;&lt;br /&gt;Errores de Diseño&lt;br /&gt;Ningún lenguaje de programación es perfecto. JavaScript tiene su porción de errores de diseño, como la sobrecarga del operador &lt;span style="font-family: courier new;"&gt;+&lt;/span&gt; para significar ambos, la suma y la concatenacion con coerción de tipos y la errorosa (error-prone) sentencia &lt;span style="font-family: courier new;"&gt;with&lt;/span&gt;, que deben ser evitados. La política de palabras reservadas es muy estrícta. La insercion del punto y coma (;) fue un gran error, como lo es la notacion para literales de expresiones regulares. Estas equivocaciones han llevado a errores de programación, que han puesto en cuestionamiento todo el diseño del lenguaje. Afortunadamente, muchos de estos problemas pueden ser mitigados con un buen programa &lt;a href="http://www.crockford.com/javascript/lint.html"&gt;lint&lt;/a&gt;. El diseño del lenguaje en general es bastante cuestionado. Sorprendentemente el comite ECMA no parece estar interesado en corregir estos errores. Quizas estan más interesados unos cuantos más.&lt;br /&gt;&lt;br /&gt;Malas implementaciones&lt;br /&gt;Algunas de las primeras implementaciones de javascript estaban llenas de errores. Esto se reflejó en el lenguaje de mala manera. Para complementar esto, esas implementaciones estaban embebidas en navegadores web horriblemente llenos de errores.&lt;br /&gt;&lt;br /&gt;Malos libros&lt;br /&gt;Practicamente todos los libros acerca de JavaScript son muy malos. Contienen errores, malos ejemplos, y promueven malas prácticas. Las carateristicas importantes del lenguaje son pobremente explicadas o dejadas de lado. He revisado docenas de libros de JavaScript y&lt;span style="font-weight: bold;"&gt; solamente recomiendo uno:&lt;/span&gt; &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596101996/wrrrldwideweb"&gt;JavaScript: The Definitive Guide (5th Edition)&lt;/a&gt; de David Flanagan.&lt;br /&gt;&lt;br /&gt;Un estandar por debajo de lo normal&lt;br /&gt;La &lt;a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm"&gt;especificación oficial del lenguaje&lt;/a&gt; es publicada por el &lt;a href="http://www.ecma-international.org/"&gt;ECMA&lt;/a&gt;. La especificación es de extrema mala calidad. Es dificil de leer y muy dificil de entender. Esto ha sido una contribución al problema de los malos libros porque los autores han sido incapaces de usar la documentacion del estandar para mejorar su propio entendimiento del lenguaje. Los comités del ECMA y él TC39 deberían estar profundamente avergonzados.&lt;br /&gt;&lt;br /&gt;Amateurs&lt;br /&gt;La mayoria de las personas escribiendo en JavaScript no son programadores. No poseen el entrenamiento y la disciplina para escribir buenos programas. JavaScript tiene tanto poder de expresión que ellos son capaces de hacer cosas utiles en él de cualquier manera. Esto le ha dado a JavaScript la reputación de ser estrictamente para amateurs, y que no se adapta para programación prefesional. Ese, simplemente no es el caso.&lt;br /&gt;&lt;br /&gt;Orientado a Objetos&lt;br /&gt;Es JavaScript orientado a objetos? tiene objetos, que pueden contener datos y métodos que actuen sobre esos datos. Los objetos pueden contener otros objetos. No tiene clases, pero tiene constructores que hacen lo que las clases hacen, incluyendo actuar como contenedor para las variables de clase y los métodos. No tiene herencia orientada a clases, pero tiene herencia prototypal.&lt;br /&gt;Los dos principales caminos para construir sistemas de objetos son herencia (es ún) y agregación (tiene ún). JavaScript hace ambos, pero su naturaleza dinámica le permite ser elegante en la agregación.&lt;br /&gt;Algunos argumentan que JavaScript no es verdaderamente orientado a objetos porque no provee ocultación de la información. Eso es que los objetos no pueden tener variables privadas o métodos privados. Todos los miembros son públicos.&lt;br /&gt;Pero resulta ser que &lt;a href="http://www.crockford.com/javascript/private.html"&gt;los objetos de JavaScript pueden tener variables privadas y métodos privados (haz click aquí si quieres saber cómo)&lt;/a&gt;. Por supuesto solo algunos van a entender esto, porque JavaScript es el lenguaje de programación más malentendido del mundo.&lt;br /&gt;Algunos argumentan que JavaScript no es verdaderamente orientado a objetos porque no provee herencia. Pero resulta ser que &lt;a href="http://javascript.crockford.com/inheritance.html"&gt;JavaScript no solamente soporta herencia clásica, sino tambien otro tipo de patrones de reutilización de código&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Copyright 2001 &lt;a href="mailto:douglas@crockford.com"&gt;Douglas Crockford.&lt;/a&gt;   &lt;a href="http://www.crockford.com/" target="_top"&gt;All Rights Reserved Wrrrldwide.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si quieres leer el original en ingles puedes encontrarlo &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0596101996/wrrrldwideweb"&gt;aquí&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-126145511492692692?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/126145511492692692/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/javascript-el-lennguaje-de-programacion.html#comment-form' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/126145511492692692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/126145511492692692'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/javascript-el-lennguaje-de-programacion.html' title='JavaScript: El Lennguaje de Programación Más Malentendido del Mundo'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-4562886762071756563</id><published>2009-03-26T10:52:00.000-07:00</published><updated>2009-03-26T11:08:53.894-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='funciones'/><category scheme='http://www.blogger.com/atom/ns#' term='avanzado'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='curry'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>currying functions</title><content type='html'>Currando funciones en javascript ja, esto es un tema avanzado asi que a todos los que se aburren mucho con mis otros post les comento que este les va a encantar.&lt;br /&gt;que son las curried functions. Simple son funciones que si reciben menos paramtros de los que deberian recibir simplemente se compilan a si mismas con los parametros que recibieron y devuelven una función que solo necesita un parametro para terminar su ejecución.&lt;br /&gt;Veamos un ejemplo simple&lt;br /&gt;supongamos que la funcion myFunc suma dos parametros&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;alert(myFunc(2,2));      // devuelve 4&lt;br /&gt;var adds4 = myFunc(4);   // adds4, es ahora una función,&lt;br /&gt;                         // que le suma 4, a lo que reciba de argumento.&lt;br /&gt;alert(adds4(5));         // devuelve 9.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;bien ahora veamos como implementar esta funcion&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function add(a, b) {&lt;br /&gt;    if (arguments.length &lt; 1) {&lt;br /&gt;&lt;br /&gt;        return add;&lt;br /&gt;&lt;br /&gt;    } else if (arguments.length &lt; 2) {&lt;br /&gt;&lt;br /&gt;        return function(c) { &lt;br /&gt;&lt;br /&gt;            return a + c &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    } else {&lt;br /&gt;&lt;br /&gt;        return a + b;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;No es mucho mas complicada, pero tampoco muy generica verdad? bueno&lt;br /&gt;podemos encontrar una solución mucho mas elegante en la siguiente funcion&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function curry(func,args,space) {&lt;br /&gt;    var n  = func.length - args.length; //arguments still to come&lt;br /&gt;    var sa = Array.prototype.slice.apply(args); // saved accumulator array&lt;br /&gt;    function accumulator(moreArgs,sa,n) {&lt;br /&gt;        var saPrev = sa.slice(0); // to reset&lt;br /&gt;        var nPrev  = n; // to reset&lt;br /&gt;        for(var i=0;i&amp;lt;moreArgs.length;i++,n--) {&lt;br /&gt;            sa[sa.length] = moreArgs[i];&lt;br /&gt;        }&lt;br /&gt;        if ((n-moreArgs.length)&amp;lt;=0) {&lt;br /&gt;            var res = func.apply(space,sa);&lt;br /&gt;            // reset vars, so curried function can be applied to new params.&lt;br /&gt;            sa = saPrev;&lt;br /&gt;            n  = nPrev;&lt;br /&gt;            return res;&lt;br /&gt;        } else {&lt;br /&gt;            return function (){&lt;br /&gt;                // arguments are params, so closure bussiness is avoided.&lt;br /&gt;                return accumulator(arguments,sa.slice(0),n);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return accumulator([],sa,n);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;como la usamos?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function add (a,b,c){&lt;br /&gt;      if (arguments.length &lt; this.add.length) {&lt;br /&gt;        return curry(this.add,arguments,this);&lt;br /&gt;      }&lt;br /&gt;      return a+b+c;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Sin embargo esta funcion no nos provee precompilación que es la verdadera gracia de curriar funciones, solo sirve para verse bonita.&lt;br /&gt;pero si quieren saber mas sobre curried functions en javascript, les recomiendo que visiten &lt;a href="http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/index.html"&gt;este link&lt;/a&gt; y vean el algoritmo de Horspool precompilado en javascript&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-4562886762071756563?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/4562886762071756563/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/currying-functions.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4562886762071756563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4562886762071756563'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/currying-functions.html' title='currying functions'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7083661244148219111</id><published>2009-03-26T08:39:00.000-07:00</published><updated>2009-03-26T09:03:43.087-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='funciones'/><category scheme='http://www.blogger.com/atom/ns#' term='avanzado'/><category scheme='http://www.blogger.com/atom/ns#' term='objetos'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><title type='text'>Un poco de Magia para empezar el dia</title><content type='html'>Hola hoy les acerco un poco de sintaxis util en javascript:&lt;br /&gt;&lt;br /&gt;Formas de crear un objeto:&lt;br /&gt;EN JAVASCRIPT TODO ES UN OBJETO y como tal no deberia ser dificil crear uno nuevo, para esto tenemos varias opciones&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var obj= new func();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;nos permite crear un objeto a partir de una funcion y utilizando su prototipo.&lt;br /&gt;Sin embargo la mejor manera de crear un obj es utilizando la notacion JSON veamos un ejemplo y lo explicamos despues&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var obj = {&lt;br /&gt;    miembro1:123,&lt;br /&gt;    meiembro2:"hola",&lt;br /&gt;    metodo1: function(){ return "metodo1";},&lt;br /&gt;    metodo2: function(){ return "metodo2";},&lt;br /&gt;    "metodo3": function(){ return "metodo3";}&lt;br /&gt;};&lt;br /&gt;alert(obj.metodo3());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;si se fijan bien la declaracion del objeto esta encerrada en llaves { }, y luego dentro se encuentran pares nombre valor separados por comas. ahora cada par nombre valor, nombre puede ser un identificador o un string y el valor puede ser cualquier valor (incluida una funcion) hasta otro objeto. Ahora hagamos un objeto complicas y juguemos con arrays&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var objc={&lt;br /&gt;    nombre:"picanteverde",&lt;br /&gt;    posicion:{x:128,y:450},&lt;br /&gt;    telefonos:[431,561,443],&lt;br /&gt;    hijos:[&lt;br /&gt;        {nombre:'Alejandro',apellido:'Hernandez',edad:26},&lt;br /&gt;        {nombre:'Emanule',apellido:'Hernandez',edad:21}&lt;br /&gt;        ],&lt;br /&gt;    hablar:function(){&lt;br /&gt;        alert(this.nombre);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;objc.hablar();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;se eniende como funciona? y lo util de JSON?? reemplaza xml?&lt;br /&gt;lo dejo a su criterio&lt;br /&gt;crear un objeto vacio&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var o ={}; // objeto vacio&lt;br /&gt;var a = []; // array vacia&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Les gusto?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7083661244148219111?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7083661244148219111/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/un-poco-de-magia-para-empezar-el-dia.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7083661244148219111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7083661244148219111'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/un-poco-de-magia-para-empezar-el-dia.html' title='Un poco de Magia para empezar el dia'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7920318576852883942</id><published>2009-03-25T23:01:00.000-07:00</published><updated>2009-03-25T23:20:15.306-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='avanzado'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprograming'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><title type='text'>Metaprogramación o DSL con javascript method chaining</title><content type='html'>Hoy vamos a ver un poco de como crear un mini &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language"&gt;Lenguaje de dominio especifico&lt;/a&gt; (como SQL, o CSS) con javscript de manera facil, rápida, elegante, agil y económica.&lt;br /&gt;Partamos de un problema.&lt;br /&gt;Supongamos que tenemos un select html de paises y solo si elijen eeuu debemos mostrar el select de estados, hariamos lo siguiente (usando la libreria prototype)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Event.observe(window, "load", function() {&lt;br /&gt;&lt;br /&gt;  Event.observe($("country"), "change", function() {&lt;br /&gt;    if ($F("country") == "United States")&lt;br /&gt;      $("state-field").show();&lt;br /&gt;    else&lt;br /&gt;      $("state-field").hide();&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;por ahora creanme que Event.observe recibe un objeto del dom, el nombre de un evento, y la funcion a attachear, $ en la lib prototype es un atajo a document.getElementById, $F es un atajo al value de un objeto de formulario, y finalmente se le agregan a los objetos del DOM dos metodos show y hide que simplemente manipulan el valor de display a nivel de css.&lt;br /&gt;&lt;br /&gt;lo importante aqui es ver que nuestro limpio codigo puede convertirse en algo mucho mas complicado si varían los requerimientos.&lt;br /&gt;&lt;br /&gt;ahora supongamos que agregamos un campo de provincias, que debe aparecer solo cuando elijamos Canada,&lt;br /&gt;y un campo brutus que solo debe aparecer cuando elijamos Michigan u Ohio&lt;br /&gt; el código elegante se empobrece y se torna dificil de leer&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Event.observe(window, "load", function() {&lt;br /&gt;&lt;br /&gt;  Event.observe($("country"), "change", function() {&lt;br /&gt;    var country = $F("country");&lt;br /&gt;    if (country == "United States") {&lt;br /&gt;      $("us-state-field").show();&lt;br /&gt;      $("province-field").hide();&lt;br /&gt;    } else if (country == "Canada") {&lt;br /&gt;      $("province-field").show();&lt;br /&gt;      $("us-state-field").hide();&lt;br /&gt;    } else {&lt;br /&gt;      $("us-state-field").hide();&lt;br /&gt;      $("province-field").hide();&lt;br /&gt;    }&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;  Event.observe($("us-state"), "change", function() {&lt;br /&gt;    var state = $F("us-state");&lt;br /&gt;    if (state == "Ohio" || state == "Michigan")&lt;br /&gt;      $("brutus").show();&lt;br /&gt;    else&lt;br /&gt;      $("brutus").hide();&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;eso sin contar que eredamos un bug que no nos oculta brutus si deseleccionamos estados unidos&lt;br /&gt;Pero eso no es importante, lo importante es ver como la legibilidad del codigo se degrado luego de haber cambiado los requerimientos (cosa que raramente pasa en el mundo real, jajajaja)&lt;br /&gt;&lt;br /&gt;Entonces como mejorar esto?&lt;br /&gt;lo mejor es intentar separar el QUE? del COMO?&lt;br /&gt;es decir separar las reglas de lo que tenemos que hacer&lt;br /&gt;de la implementación de como hacerlo.&lt;br /&gt;entonces veamos como creariamos un pequeño lenguaje que nos permita definir esto&lt;br /&gt;para crear un lenguaje vamos a utilizar el lenguaje natural mas parecido al lenguaje del dominio del problema, (pero ahora lo vamos a hacer en ingles).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;show us-state when country is “United States”&lt;br /&gt;show province when country is “Canada”&lt;br /&gt;show Brutus when state is “Ohio” or “Michigan”&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ahora como convertimos esto en javascript, simple&lt;br /&gt;creando objetos que se encarguen de la implementación teniendo en cuenta el orden de llamadas de metodos&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;show("us-state-field").when("country").is("United States");&lt;br /&gt;show("province-field").when("country").is("Canada");&lt;br /&gt;show("brutus").when("us-state").is("Ohio,Michigan");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;para ver como implementariamos estos metodos los voy a dejar en suspenso hasta un proximo encuentro&lt;br /&gt;ja&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.adamlogic.com/2007/03/28/6_metaprogramming-javascript-part-1"&gt;fuente&lt;/a&gt;&lt;br /&gt;&lt;a href="http://livepipe.net/extra/event_behavior"&gt;libreria Event.behavior&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7920318576852883942?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7920318576852883942/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/metaprogramacion-o-dsl-con-javascript.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7920318576852883942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7920318576852883942'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/metaprogramacion-o-dsl-con-javascript.html' title='Metaprogramación o DSL con javascript method chaining'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-5092448980304733418</id><published>2009-03-25T21:56:00.000-07:00</published><updated>2009-03-25T22:01:17.492-07:00</updated><title type='text'>Vamos a soñar despiertos</title><content type='html'>yo soy de los que opinan que las majores ideas para los browsers del futuro la dan los que hacen los mejores browser del presente:&lt;br /&gt;&lt;br /&gt;Mozilla le pidio a Jesse James Garrett (muchacho que en el 2004 dijo, si convinamos javascript html y xml tenemos AJAX) que diseñe conceptualmente como deberían ser los browser dentro de 10 a 50 años. Si se fijan bien muchos de los conceptos son realizables ya hoy en dia mediante javascript.pero mejor los dejo con el video disfrutenlo en HD&lt;br /&gt;es el ultimo link.&lt;br /&gt;Saluts&lt;br /&gt;&lt;br /&gt;&lt;a href="http://labs.mozilla.com/projects/concept-series/"&gt;http://labs.mozilla.com/projects/concept-series/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://adaptivepath.com/aurora/"&gt;http://adaptivepath.com/aurora/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.vimeo.com/1450211"&gt;http://www.vimeo.com/1450211&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-5092448980304733418?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/5092448980304733418/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/vamos-sonar-despiertos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5092448980304733418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5092448980304733418'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/vamos-sonar-despiertos.html' title='Vamos a soñar despiertos'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-1097107360818371232</id><published>2009-03-25T21:45:00.000-07:00</published><updated>2009-03-25T21:53:33.267-07:00</updated><title type='text'>Mi sueño se hizo realidad (Otra vez)</title><content type='html'>asi es, siempre quise tener un buen editor de código con resaltador de sintaxis multi lenguaje (php,javascript,css,html) y aunque &lt;a href="http://javascriptexperts.blogspot.com/2009/03/bespin-editando-codigo-en-la-nube.html"&gt;bespin&lt;/a&gt; es un proyecto muy en serio que ataca este problema, esta escrito en python y no es nada facil de instalar en tu hosting. Pero ahora tenemos a &lt;a href="http://ecoder.gmeditor.com/"&gt;ecoder&lt;/a&gt; que es una aplicacion php que te permite editar tu código en linea. Como un gran amigo mio siempre decía, "Los cambios se implementan en el entorno de producción, ja!". Disfrutenlo, y aunque todavia está en una etapa muy beta, se que vamos a seguir escuchando noticias de él. &lt;br /&gt;&lt;br /&gt;Notas: es un tanto dificil de instalar ya que tiene muy poca documentación (los comments del código) pero si son bueno php-hackers se las van a arreglar muy bien.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ecoder.gmeditor.com/"&gt;ecoder&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-1097107360818371232?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/1097107360818371232/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/mi-sueno-se-hizo-realidad-otra-vez.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/1097107360818371232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/1097107360818371232'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/mi-sueno-se-hizo-realidad-otra-vez.html' title='Mi sueño se hizo realidad (Otra vez)'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7022581828632053687</id><published>2009-03-25T10:34:00.000-07:00</published><updated>2009-03-25T12:05:21.785-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='funciones'/><category scheme='http://www.blogger.com/atom/ns#' term='basico'/><category scheme='http://www.blogger.com/atom/ns#' term='objetos'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Como programar en Javascript</title><content type='html'>Javascript es un &lt;a href="http://es.wikipedia.org/wiki/Programación_funcional"&gt;lenguaje funcional&lt;/a&gt; esto implica que sus construcciones de codigo son simplemente funciones. Pero no implica que solamente se pueda programar en formato funcional ya que podemos aplicar muchos paradigmas. Como por Ejemplo el paradigma orientado a objetos.&lt;br /&gt;&lt;br /&gt;Como dijimos antes EN JAVA SCRIPT TODO ES UN OBJETO, inclusive las funciones, pero no existen las clases, y esto nos presenta una dificultad como trabajar con el paradigma orientado a objetos.&lt;br /&gt;&lt;br /&gt;supongamos que necesitamos crear una persona con dos miembros, un nombre y un apellido, y un metodo hablar que nos alertará el nombre y el apellido.&lt;br /&gt;veamos como hacer esto&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function persona (pNombre, pApellido){&lt;br /&gt;    this.nombre = pNombre;&lt;br /&gt;    this.apellido= pApellido;&lt;br /&gt;}&lt;br /&gt;persona.prototype.hablar = function (){&lt;br /&gt;    alert(this.apellido + ", " + this.nombre);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var a = new persona("picante","verde");&lt;br /&gt;a.hablar();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;funcamentalmente entendamos una cosa, &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function persona (pNombre, pApellido){ ... }&lt;br /&gt;es un atajo de &lt;br /&gt;var persona = function (pNombre, pApellido){ ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;prototype es el prototypo de un objeto (no es la clase, pero podemos decir que es algo parecido (ah y tambien es un objeto)).&lt;br /&gt;Entonces si creamos un nuevo miembro en el prototypo, simplemente asignandolo&lt;br /&gt;vamos a crear un nuevo miembro en todos los objetos que hayan sido creados a travez de ese prototypo.&lt;br /&gt;la cuestion es mucho mas compleja pero por ahora pueden quedarse con esa idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7022581828632053687?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7022581828632053687/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/como-programar-en-javascript.html#comment-form' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7022581828632053687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7022581828632053687'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/como-programar-en-javascript.html' title='Como programar en Javascript'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7752252751133389215</id><published>2009-03-24T22:50:00.000-07:00</published><updated>2009-03-25T10:31:42.319-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='3d'/><title type='text'>Javascript 3d</title><content type='html'>Si javascript trabaja con 3d hace mucho tiempo pero ultimamente han avanzado más que nunca asi podemos ver como esta aplicación renderiza en 3d inclusive con reflejos en las texturas&lt;br /&gt;&lt;br /&gt;&lt;a href="http://gyu.que.jp/jscloth/touch.html"&gt;fuente&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7752252751133389215?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7752252751133389215/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/javascript-3d.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7752252751133389215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7752252751133389215'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/javascript-3d.html' title='Javascript 3d'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-9174567722409910264</id><published>2009-03-24T22:48:00.000-07:00</published><updated>2009-03-25T10:32:04.712-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='ocr'/><title type='text'>OCR con javascript?</title><content type='html'>Como verán javascript no deja de sorprenderme jamas y pueden ver aqui como algunos hackers se la ingeniaron para saltar el &lt;a href="http://es.wikipedia.org/wiki/Captcha"&gt;captcha&lt;/a&gt; de megaupload solo utilizando javascript&lt;br /&gt;&lt;br /&gt;&lt;a href="http://userscripts.org/scripts/review/38736"&gt;fuente&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-9174567722409910264?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/9174567722409910264/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/ocr-con-javascript.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/9174567722409910264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/9174567722409910264'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/ocr-con-javascript.html' title='OCR con javascript?'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8231841913483556879</id><published>2009-03-24T22:40:00.000-07:00</published><updated>2009-03-25T10:32:30.043-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='bookmarklets'/><title type='text'>Bookmarklets</title><content type='html'>A travez de &lt;a href="http://www.anieto2k.com"&gt;aNieto2k&lt;/a&gt; vengo a enterarme de que los bookmarklets son pequeños scripts escritos obviamente en javascript y que pueden ser almacenados en tus favoritos (Bookmarks) y ejecutados a tu gusto.&lt;br /&gt;Todo esto gracias a que si en la barra de direcciones de tu navegador escribes&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;javascript:alert("hola");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;puedes ejecutar codigo javascript, que se ejecuta dentro del entorno de la página que tengas abierta en ese momento&lt;br /&gt;&lt;br /&gt;si no me crees, ingresa a una página con muchas imagenes y copia el siguiente codigo javascript dentro de tu barra de direcciones y presiona enter&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;javascript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.getElementsByTagName("img"); DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=(Math.sin(R*x1+i*x2+x3)*x4+x5)+"px"; DIS.top=(Math.cos(R*y1+i*y2+y3)*y4+y5)+"px"}R++}setInterval('A()',5); void(0); &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Saludos&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.anieto2k.com/2009/02/17/bookmarklets-para-desarrolladores-web/"&gt;Bookmarklets para desarrolladores web en aNieto2k&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8231841913483556879?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8231841913483556879/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/bookmarklets.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8231841913483556879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8231841913483556879'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/bookmarklets.html' title='Bookmarklets'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7591465209993224820</id><published>2009-03-24T22:31:00.000-07:00</published><updated>2009-03-24T22:40:23.068-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='editores'/><category scheme='http://www.blogger.com/atom/ns#' term='bespin'/><category scheme='http://www.blogger.com/atom/ns#' term='mozilla'/><title type='text'>Bespin, editando codigo en la nube</title><content type='html'>Magnifico, los muchachos de mozilla se encargaron de crear un genial editor de texto multilenguaje con resaltador de sintaxis (justo como a nosotros nos gusta)&lt;br /&gt;se llama &lt;a href="https://bespin.mozilla.com/"&gt;Bespin&lt;/a&gt; y pueden leer mas sobre el &lt;a href="http://labs.mozilla.com/projects/bespin/"&gt;aca&lt;/a&gt; pienso yo que es una gran alternativa a los viejos &lt;a href="http://es.wikipedia.org/wiki/Entorno_de_desarrollo_integrado"&gt;IDE&lt;/a&gt; que no son tan optimos para el desarrollo web. Asi que ahora los web developers contamos con una excelente alternativa a programas como&lt;br /&gt;&lt;a href="http://www.contexteditor.org/"&gt;context&lt;/a&gt;&lt;br&gt;&lt;br /&gt;&lt;a href="http://notepad-plus.sourceforge.net/es/site.htm"&gt;Notepad ++&lt;/a&gt;&lt;br /&gt;y el glorioso &lt;a href="http://kate-editor.org/"&gt;Kate&lt;/a&gt; que siempre fue el que mas usé.&lt;br /&gt;&lt;br /&gt;Bespin esta programado en python y es posible bajar el codigo fuente e instalarlo en tu propio servidor (pero no facil).&lt;br /&gt;Como detalle me gustaría agregar que el editor de codigo de Bespin esta basado en el objeto canvas de html por lo que no podrás usarlo con navegadores que no soporten este objeto.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7591465209993224820?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7591465209993224820/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/bespin-editando-codigo-en-la-nube.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7591465209993224820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7591465209993224820'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/bespin-editando-codigo-en-la-nube.html' title='Bespin, editando codigo en la nube'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8020876735813499868</id><published>2009-03-24T21:58:00.000-07:00</published><updated>2009-03-24T22:30:40.178-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='basico'/><category scheme='http://www.blogger.com/atom/ns#' term='lambda'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='lenguaje'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Funciones Lambda</title><content type='html'>Despues de mi post de &lt;a href="http://javascriptexperts.blogspot.com/2009/03/closures.html"&gt;closures&lt;/a&gt; sentí que debería haber explicado un poco de funciones lambda antes y su funcionalidad, el nombre lambda viene del &lt;a href="http://es.wikipedia.org/wiki/C%C3%A1lculo_lambda"&gt;calculo lambda &lt;/a&gt;que es una teoría matematica tan complicada que excede el alcance de este post, este blog y este autor asi que les dejo la tarea de investigación a ustedes.&lt;br /&gt;Basicamente son funciones sin nombre, pero en javascript esto tiene mucha mayor profundidad, ya que lo que sucede en realidad es que &lt;span style="font-weight: bold;"&gt;EN JAVASCRIPT TODO ES UN OBJETO&lt;/span&gt; y me gustaría que eso quede claro por eso lo voy a repetir &lt;span style="font-weight: bold;"&gt;EN JAVASCRIPT TODO ES UN OBJETO&lt;/span&gt; , entonces hasta las funciones son objetos.&lt;br /&gt;Por tanto es indistinto escribir cualquiera de las dos declaraciones de funciones siguientes.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function FuncX(){&lt;br /&gt;    return "x";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var FuncY = function (){&lt;br /&gt;    return "y";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;de esta forma podemos ver que podemos asignar una funcion a una variable y siempre que declaramos funciones implicitamente estamos declarando variables con el nombre de la funcion.&lt;br /&gt;&lt;br /&gt;para ver esto llevado al extremo podemos ver el siguiente ejemplo&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var funcRec = function(){&lt;br /&gt;    return function(){&lt;br /&gt;        return funcRec();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;alert(funcRec()()()()()()()()()()()()); // que devuelve????&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;a decir verdad esto es muy simple. la funcion funcRec devuelve una funcion (lambda) anonima, que al ser ejecutada devuelve el valor de la llamada a funcRec.&lt;br /&gt;entonces &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;funcRec() //devuelve una funcion que al ser ejecutada devolverá el valor de ejecutar funcRec()&lt;br /&gt;funcRec()()// ejecuta la funcion devuelta por la primer ejecucion, la cual devuelve exactamente lo mismo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;confuso verdad, bueno espero que lo lean muchas veces hasta que lo entiendan. Les dejo algo más elaborado para ver si les sirve.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;var a=0;&lt;br /&gt;var funcRec = function(){&lt;br /&gt;&lt;br /&gt;    alert("a=" + a);&lt;br /&gt;    return function(){&lt;br /&gt;        a+=1;&lt;br /&gt;        return funcRec();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;alert(funcRec()()());&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8020876735813499868?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8020876735813499868/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/funciones-lambda.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8020876735813499868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8020876735813499868'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/funciones-lambda.html' title='Funciones Lambda'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-8661234180711282740</id><published>2009-03-24T21:32:00.000-07:00</published><updated>2009-03-24T21:58:07.697-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='basico'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='lenguaje'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Closures</title><content type='html'>Las &lt;a href="http://es.wikipedia.org/wiki/Clausura_%28inform%C3%A1tica%29"&gt;closures &lt;/a&gt;son una parte vital del paradigma de &lt;a href="http://es.wikipedia.org/wiki/Programaci%C3%B3n_funcional"&gt;Programación Funcional&lt;/a&gt; asi que vamos a darle una pequeña mirada a este concepto para aclarar las cosas un poco. Una closure es cuando definimos una funcion esta tiene acceso a las variables del entorno donde fue definida. Aun si la ejecución de ese entorno finalizó. Veamos un ejemplo porque estoy seguro que nadie entendio nada ja.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;  function outer(c, d) {&lt;br /&gt;       var e = c * d;&lt;br /&gt;&lt;br /&gt;       function inner(a, b) {&lt;br /&gt;           return (e * a) + b;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       return inner(2, 1);&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;como pueden ver en este simple ejemplo definimos una función dentro de otra sin embargo podemos ver que la funcion inner tiene acceso a la variable &lt;span style="font-weight: bold;"&gt;e&lt;/span&gt; que fue definida fuera de la funcion.&lt;br /&gt;entonces si llamamos la funcion&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;outer(3,2)    // returns 13&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ahora veamos a que me refiero con que no importa si la funcion outter ya finalizó su ejecución.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function crearFuncion(c){&lt;br /&gt;    var a=3;&lt;br /&gt;    var b=4;&lt;br /&gt;    var func = function(x){&lt;br /&gt;        return a*b*c*x;&lt;br /&gt;    }&lt;br /&gt;    return func;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;como podemos ver este ejemplo es aun más complicado pero nos permite reflejar el hecho de que en Javascript todo es un objeto, hasta las funciones son objetos y como las funciones pueden recibir objetos como parametros, y pueden devolver objetos, entonces tambien pueden recibir funciones y devolver funciones.&lt;br /&gt;Veamos como utilizariamos esto&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var f = crearFuncion(2);&lt;br /&gt;alert(f(5)) // alerts 120 ( = 2*3*4*5)&lt;br /&gt;&lt;br /&gt;// que ocurriría si hiciesemos ...&lt;br /&gt;alert(crearFuncion(2)(5))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;allí podemos ver que la funcion func (declarada dentro de crearFuncion) puede seguir utilizando las variables a,b,c (declarados dentro de crearFuncion) aún despues de que la ejecución de crearFuncion haya terminado.&lt;br /&gt;&lt;br /&gt;eso son closures!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-8661234180711282740?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/8661234180711282740/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/closures.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8661234180711282740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/8661234180711282740'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/closures.html' title='Closures'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-4508070933318421487</id><published>2009-03-24T21:29:00.000-07:00</published><updated>2009-03-24T21:32:54.313-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Douglas Crockford'/><category scheme='http://www.blogger.com/atom/ns#' term='lenguaje'/><title type='text'>Como escribir buen Javascript</title><content type='html'>Una vez más nuestro amigo Douglas se ha esforzado en traernoes este espectacular compendio de consejos para escribir buen codigo javascript como pueden ver en &lt;a href="http://javascript.crockford.com/code.html"&gt;Convenciones de Código para el Lenguaje de Programación Javascript&lt;/a&gt; es una excelente idea y una buena practica tener estos consejos en mente a medida que creemos nuestros programas (aunque muchas veces estemos apurados jaja)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-4508070933318421487?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/4508070933318421487/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/como-escribir-buen-javascript.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4508070933318421487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/4508070933318421487'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/como-escribir-buen-javascript.html' title='Como escribir buen Javascript'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-6796899326485808673</id><published>2009-03-24T21:20:00.000-07:00</published><updated>2009-03-24T21:29:29.671-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Beyond JS'/><category scheme='http://www.blogger.com/atom/ns#' term='avanzado'/><category scheme='http://www.blogger.com/atom/ns#' term='librerias'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Beyond JS</title><content type='html'>Ahora que ya he dedicado mi (segundo) primer Post del blog a Douglas quisiera comentarles sobre esta libreria muy poco conocida que encontré en la red, se llama &lt;a href="http://w3future.com/html/beyondJS/"&gt;Beyond JS&lt;/a&gt; y aunque no es una libreria que utilizaría dia a dia realmente me dejó pensando. aqui un Ejemplo de su utilización para que se deleiten&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;document.body.onmousemove = Function.from("star", "moveTo").delay(1000).using(&lt;br /&gt; "+".using(&lt;br /&gt;   Function.from(event, Ã),&lt;br /&gt;   "*".using("radius", Function.from(Math, "sin", "angle"))),&lt;br /&gt; "+".using(&lt;br /&gt;   Function.from(event, "y"),&lt;br /&gt;   "*".using("radius", Function.from(Math, "cos", "angle")))&lt;br /&gt;).curry({&lt;br /&gt; radius: 30,&lt;br /&gt; angle: function() {return (new Date)/50;}.asValue()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Como pueden ver hace arto uso de &lt;a href="http://docs.jquery.com/How_jQuery_Works#Chainability_.28The_Magic_of_jQuery.29"&gt;function Chaining&lt;/a&gt; (que conocí gracias a &lt;a href="http://jquery.com/"&gt;jquery&lt;/a&gt;)&lt;br /&gt;y además obtiene las referencias a funciones a las funciones mediante el Function.from&lt;br /&gt;el resto la verdad que requiere un analisis más largo pero eso se los dejo a ustedes.&lt;br /&gt;Ah! una cosa más ven ese &lt;span style="font-weight: bold;"&gt;curry&lt;/span&gt; bueno vamos a hablar un poco de eso más tarde&lt;br /&gt;}).gate(Function.from("doStar".element(),"checked"));&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-6796899326485808673?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/6796899326485808673/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/beyond-js.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6796899326485808673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6796899326485808673'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/beyond-js.html' title='Beyond JS'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-7768669039035342248</id><published>2009-03-24T21:12:00.000-07:00</published><updated>2009-03-24T21:20:29.665-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='teorias'/><category scheme='http://www.blogger.com/atom/ns#' term='Douglas Crockford'/><title type='text'>Dedicado a Douglas</title><content type='html'>Vamos a arrancar con una fuente inagotable de maravillas de este lenguaje, la página de &lt;a href="http://javascript.crockford.com/"&gt;javascript&lt;/a&gt; de &lt;a href="http://www.crockford.com/"&gt;Douglas Crockford&lt;/a&gt; alli podrán encontrar el Magistral articulo &lt;a href="http://javascript.crockford.com/javascript.html"&gt;Javascript: El Lenguaje de Programación más Malentendido del Mundo&lt;/a&gt; que está solamente en ingles pero que REALMENTE vale la pena leer, junto con &lt;a href="http://javascript.crockford.com/popular.html"&gt;El Lenguaje de Programación más Malentendido del Mundo se ha Vuelto el Lenguaje de Programación más Popular del Mundo&lt;/a&gt; (asi es parece que Douglas disfruta de los titulos largos) espero que les resulte tan interesante y divertido como me resulto a mi&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-7768669039035342248?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/7768669039035342248/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/dedicado-douglas.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7768669039035342248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/7768669039035342248'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/dedicado-douglas.html' title='Dedicado a Douglas'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-6950600986055597878</id><published>2009-03-24T21:09:00.000-07:00</published><updated>2009-03-24T21:12:28.992-07:00</updated><title type='text'>Abriendo el Blog 2.0</title><content type='html'>Ja pasados unos dias me di cuenta que practicamente semanalmente le enviaba a un grupo selecto de amigos las noticias que me habian parecido importantes sobre Javascript mi lenguaje favorito. Entonces me dije a mi mismo "deberia abrirme un blog" y luego recorde "ya lo abrí un tiempo atras" (solo que olvide postear cosas ja) asi que decidí volver a la carga a hablar con todos ustedes de lo mucho que disfruto aprender algo nuevo todos los dias con este lenguaje.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-6950600986055597878?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/6950600986055597878/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/abriendo-el-blog-20.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6950600986055597878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/6950600986055597878'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2009/03/abriendo-el-blog-20.html' title='Abriendo el Blog 2.0'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-2426281064992951699</id><published>2008-10-24T05:30:00.000-07:00</published><updated>2008-10-24T05:49:01.913-07:00</updated><title type='text'>Controlando eventos</title><content type='html'>Por el post anterior recibi una pregunta muy interesante:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;Con el tema de eventos, estaba viendo q en GMAIL, cuando aparece una direccion de correo, aparece el clasico "mailto:" con parte del href del anchor.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;Pero en lugar de levantar el clasico outlook o tu gestor de mail pop3, levanta en ventana aparte una pagina donde nos permite redactar el mail.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-family:trebuchet ms;" &gt;Como se puede lograr esto??&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;es muy simple las funciones que son asignadas en los eventos pueden devolver un valor true o false (a decir verdad todas las funciones en javascript pueden devolver un valor por más que no sea utilizado cuando se llamó a la funcion). El punto es que si una funcion asignada a un evento devuelve False, esto evita que el comportamiento normal para ese evento continue (que no es lo mismo que cancelar la burbuja de eventos para los entendidos).&lt;br /&gt;gracias a esto podemos decir entonces:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;a id="linkid" href="mailto:hola@gmail.com"&amp;gt;link&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;var link = document.getElementById("linkid");&lt;br /&gt;link.onclick=function(){&lt;br /&gt; alert("aqui puedo hacer lo que quiera");&lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;probado en firefox 3 y IE 6 (si funciona en IE 6 , lo podemos hacer funcionar en cualquier cosa)&lt;br /&gt;Esto esta bueno porque podemos permitir cierto comportamiento comun del navegador, como click derecho-&gt;copiar ruta del enlace, y se copia el enlace bien, pero al momento del click podemos cambiar el link al que se dirije y listo.&lt;br /&gt;&lt;br /&gt;lo que es cierto es que tambien podemos probar en los eventos onmousedown y onmouseup pero eso se los dejo a ustedes asi se divierten&lt;br /&gt;&lt;br /&gt;Saludos y sigan mandando preguntas&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-2426281064992951699?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/2426281064992951699/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2008/10/controlando-eventos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2426281064992951699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/2426281064992951699'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2008/10/controlando-eventos.html' title='Controlando eventos'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6000240755870692859.post-5070469195334911869</id><published>2008-10-23T07:52:00.000-07:00</published><updated>2008-10-23T08:08:31.466-07:00</updated><title type='text'>Javascript Events en el DOM</title><content type='html'>Los eventos javascript son más complicados de lo que uno cree&lt;br /&gt;hay tres modelos importantes que entender&lt;br /&gt;el modelo &lt;a href="http://www.quirksmode.org/js/events_tradmod.html"&gt;Tradicional&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;function hacerAlgo(){&lt;br /&gt; alert('lo hice');&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;obj.onclick= hacerAlgo;&lt;br /&gt;&lt;br /&gt;donde los eventos son miembros seteables de un objeto.&lt;br /&gt;Como la mayoria de ustedes sabrá obviamente podemos utilizar funciones anonimas (lambda) para asignar los eventos&lt;br /&gt;&lt;br /&gt;obj.onclick= function(){&lt;br /&gt;  alert('hizo click')&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;todos los navegadores soportan este modelo de eventos, el unico problema es que no es facil poder contar con el objeto event ni con el objeto que recivió el evento de una manera cross browser debido a la (mala) implementación de IE (trident) veamos un ejemplo&lt;br /&gt;&lt;br /&gt;supongamos un elemento div con id="el_div"&lt;br /&gt;&lt;br /&gt;var obj = document.getElementById("el_div");&lt;br /&gt;obj.onclick = function (e){&lt;br /&gt;   // en la mayoria de los browsers compatibles con&lt;br /&gt;   //w3c el parametro e de la funcion posee el objeto event&lt;br /&gt;   // en IE el objeto esta en window.event&lt;br /&gt;   e = e || window.event;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;de esta forma tenemos el objeto event en la variable e&lt;br /&gt;gracias a la utilizacion del operador default (||)&lt;br /&gt;el uso del operador default tambien conocido como operador logico OR es muy simple&lt;br /&gt;si el primer operando devuelve un valor truthy (verdaderoso o distinto de null o 0) entonces devuelve el primer operando, de lo contrario devuelve el segundo operando. simple y maravilloso&lt;br /&gt;&lt;br /&gt;bueno por ahora les dejo los modelos avanzados en un link pero despues vuelvo con mas comentarios&lt;br /&gt;&lt;a href="http://www.quirksmode.org/js/events_advanced.html"&gt;modelos avanzados segun ppk&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6000240755870692859-5070469195334911869?l=javascriptexperts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javascriptexperts.blogspot.com/feeds/5070469195334911869/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://javascriptexperts.blogspot.com/2008/10/javascript-events-en-el-dom.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5070469195334911869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6000240755870692859/posts/default/5070469195334911869'/><link rel='alternate' type='text/html' href='http://javascriptexperts.blogspot.com/2008/10/javascript-events-en-el-dom.html' title='Javascript Events en el DOM'/><author><name>Alejandro Hernández</name><uri>http://www.blogger.com/profile/05973767960391636526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
