<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>fernetjs</title>
	<atom:link href="http://fernetjs.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fernetjs.com</link>
	<description>fernet + javascript</description>
	<lastBuildDate>Tue, 23 Apr 2013 17:19:08 +0000</lastBuildDate>
	<language>es-ES</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Aprendiendo Bootstrap en 5 días</title>
		<link>http://fernetjs.com/2013/04/aprendiendo-bootstrap-en-5-dias/</link>
		<comments>http://fernetjs.com/2013/04/aprendiendo-bootstrap-en-5-dias/#comments</comments>
		<pubDate>Tue, 23 Apr 2013 17:19:08 +0000</pubDate>
		<dc:creator>Claudia Blatter</dc:creator>
				<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[bootstrap]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3662</guid>
		<description><![CDATA[Hola comunidad ! Somos un equipo de desarrollo que estos días tuvo el desafío de aprender bootstrap en 5 días. ... <br /><a class="more-link" href="http://fernetjs.com/2013/04/aprendiendo-bootstrap-en-5-dias/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Hola comunidad !</p>
<p>Somos un equipo de desarrollo que estos días tuvo el desafío de aprender bootstrap en 5 días. Qué resultó? Acá va nuestra experiencia:</p>
<p><b>El primer día</b></p>
<ol>
<li>Entendimos que nuestro cliente nos pedía que las pantallas web empiecen a ser responsive y hoy no lo son. Así que el desafío fue tomar la maqueta del cliente (maqueta.png) y hacer la pantalla desde cero y responsive!</li>
<li>Aprendimos que responsive significa que la página se adapta al ancho del dispositivo (monitor, ipad, iphone, etc).</li>
<li>Y que <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> es un framework que con HTML y CSS, facilita la definición de un layout de páginas web, y además, te da la posibilidad de que tus páginas sean responsive.</li>
<li>Empezamos a armar la estructura de la página con el concepto que, por defecto, Bootstrap usa 12 columnas imaginarias en un ancho de 940 pixeles.</li>
<li>Usamos <a href="http://www.colorzilla.com/">Collorzilla</a> para obtener los colores de la maqueta y MeasureIt para obtener las medidas.</li>
<li>Conseguimos un html con un montón de div porque la maqueta tiene unas cuantas divisiones!</li>
</ol>
<p><b>El segundo día</b></p>
<ol>
<li>La página que tenemos ya es responsive.</li>
<li>Discutimos un poco acerca de las nomenclaturas para los nombres de las clases de estilo y acordamos que tengan el prefijo del proyecto cuando son clases propias (p.e. pnt-home).</li>
<li>Nos organizamos para trabajar en 2 parejas de trabajo.</li>
<li>Una pareja decidió avanzar de a bloques y otra decidió armar primero la página y luego estilarla.</li>
<li>Bootstrap no nos ayudó en el diseño y si nos facilitó para que sea responsive.</li>
<li>Fundamental que cada bloque que usamos para el layout de la página tiene que tener row y/o span, y los estilos se aplican al contenido, no antes!</li>
</ol>
<p><b>El tercer día</b></p>
<ol>
<li>Bootstrap significa autosuficiente, nada, para saber de dónde el nombre.</li>
<li>Empezamos a paralelizar el laburo de diseño.</li>
<li>Y a usar componentes propios de Bootstrap como dropdown, tabs, pills.</li>
<li>Vemos que Bootstrap va bien para páginas con pocas secciones y con muchas subdivisiones se complican los márgenes predefinidos de la página.</li>
</ol>
<p><b>El cuarto día</b></p>
<ol>
<li>Bootstrap nos ayuda a utilizar los elementos HTML para lo que fueron creados.</li>
<li>Se nos complica imitar formatos de la maqueta inicial.</li>
</ol>
<p><b>El quinto día</b></p>
<ol>
<li>Incorporamos <a href="http://fortawesome.github.io/Font-Awesome/">Font Awesome</a> para que los íconos y letras sean escalables y de calidad, altamente recomendable!</li>
<li>Usamos responsive navbar para que la página convierta una fila de títulos en opciones de menú cuando achicas la pantalla.</li>
<li>Terminamos el desafío haciendo una demo de lo logrado.</li>
</ol>
<p>Una forma simpática de aprender en equipo.</p>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/04/aprendiendo-bootstrap-en-5-dias/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>NodeJS a la nube con NGINX en un VPS</title>
		<link>http://fernetjs.com/2013/03/nodejs-a-la-nube-con-nginx-en-un-vps/</link>
		<comments>http://fernetjs.com/2013/03/nodejs-a-la-nube-con-nginx-en-un-vps/#comments</comments>
		<pubDate>Mon, 25 Mar 2013 15:24:37 +0000</pubDate>
		<dc:creator>Pablo Novas</dc:creator>
				<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[vps]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3623</guid>
		<description><![CDATA[Anteriormente expliqué como poner productiva una app en NodeJS utilizando PaaS en NodeJS con Nodejitsu y Nodester, pero hace poco ... <br /><a class="more-link" href="http://fernetjs.com/2013/03/nodejs-a-la-nube-con-nginx-en-un-vps/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Anteriormente expliqué como poner productiva una app en NodeJS utilizando PaaS en <a href="http://fernetjs.com/2012/07/nodejs-en-la-nube-con-nodejitsu-y-nodester/" title="NodeJS en la nube con Nodejitsu y Nodester">NodeJS con Nodejitsu y Nodester</a>, pero hace poco me puse a investigar para ir mas allá, así que me compré un VPS (Servidor Virtual Privado) e incursioné en el desafío.</p>
<p>Comprar un VPS, instalar una distribución de linux y configurar Node es bastante sencillo, luego bajar nuestro proyecto y ponerlo en funcionamiento tampoco tiene muchas vueltas, es lo mismo que en local en nuestras maquinas (todo por terminal/ consola). Pero la idea de un VPS es que no vamos a tener un solo proceso node, tenemos un servidor para nosotros, vamos a meter muchos procesos, varias bases de datos, la idea es que vamos más allá de una app en nodejs.</p>
<h3>El puerto 80</h3>
<p>Nos levantamos un servidor node en el puerto 80, y ahora?, no podemos usar el mismo puerto para otro servidor, pero queremos que la IP de nuestro VPS sirva ambos servidores.<br />
Por ejemplo tener ejemplo.com y ejemplo2.com en el mismo servidor pero en 2 procesos distintos, es decir, cada proceso con un puerto diferente, pero para el usuario es el 80.</p>
<h3>Virtual Hosts</h3>
<p>Básicamente un virtual host nos va a permitir realizar un <a href="http://es.wikipedia.org/wiki/Proxy#Reverse_Proxy_.2F_Proxy_inverso">reverse proxy</a>, es decir, cada request que nos ingresa al servidor por el puerto 80, manejamos que proceso de node sirve fijándonos el dominio por le que ingresó.</p>
<p>Bueno, hay algunas opciones para hacer esto en forma visual (que dependen de la distribución linux que hayamos elegido).<br />
Para mi caso voy a ir con CentOS 6, para complicarla bien, ni siquiera podemos usar <a href="http://lxcenter.org/software/kloxo">Kloxo</a> (en la ver. 6 de CentOS), también tenemos otras opciones como puede ser <a href="http://www.webmin.com/">WebMin</a>, pero investigando un poco más me encontré con un punto interesante: si tenemos un VPS, donde lo importante (y limitante al bolsillo) es la transferencia mensual (entre otras cosas), no nos conviene utilizar estas herramientas web que simplemente al configurar vamos a estar consumiendo los recursos. No digo que es un limitante, pero es un punto importante aunque también es mas divertido meter mano lo máximo que se pueda. Así que descartemos estas herramientas.</p>
<h3>Apache vs NGINX</h3>
<p>Los que hayan usado Apache (por ejemplo para PHP) conocerán que es bastante simple configurar Virtual Hosts, pero yo tenia NodeJS, no PHP, y casualmente con Apache no vamos a estar utilizando el potencial de NodeJS así que seguí investigando y me encontré con NGINX, el cual es orientado a eventos, por lo que sería ideal para nuestro caso donde tenemos varios procesos NodeJS.</p>
<h3>Instalando NGINX</h3>
<p>La instalación va a depender de la Distribución de Linux / el SO que elijamos, para el caso de CentOS va por yum</p>
<pre class="brush: bash; title: ; notranslate">
wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
rpm -ivh nginx-release-centos-6-0.el6.ngx.noarch.rpm
yum install nginx
</pre>
<h3>Configurando NGINX</h3>
<blockquote><p>
Como conté al inicio del post, es la primera vez que me meto en todo esto, así que la configuración que les voy a mostrar es lo básico para poner en funcionamiento nuestros servidores NodeJS, no mas que eso.
</p></blockquote>
<p><a href="http://wiki.nginx.org/Main">nginx</a> (se pronuncia enyinex, como Engine X en inglés <img src='http://fernetjs.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ), a diferencia de Apache, actual como un ReverseProxy antes que un HTTP Server. Y su configuración es parecida a un JSON con una suerte de herencia jerárquica, es decir, las configuraciones de abajo reemplazan a las de arriba (<a href="http://blog.martinfjordvald.com/2012/08/understanding-the-nginx-configuration-inheritance-model/">dependiendo el caso</a>)</p>
<p>Sin meterme mucho en la configuración, ya que desconozco ampliamente (pueden ver mas <a href="http://blog.martinfjordvald.com/2010/07/nginx-primer/">acá</a>), tenemos 3 componentes importantes:</p>
<p>http > server > location : donde <em>server</em> serían el equivalente al VirtualHost en Apache y <em>location</em> las rutas a los recursos (URIs).</p>
<p>Entonces, para nuestro caso particular donde queremos 2 procesos nodejs utilizando dominios distintos y que ambos sean accesibles desde la misma IP (de nuestro VPS) bajo el puerto 80, deberíamos crear un http, con 2 <em>server</em> y sus respectivas <em>location</em> (URI raíz) apuntando a nuestros procesos.</p>
<p>Así que primero, configuramos nuestros procesos de Node para que corran, por ejemplo, uno en el puerto 3000 y el otro en el 3050 y después armemos el config:</p>
<p>Abrimos el archivo de configuración para Linux:</p>
<pre class="brush: bash; title: ; notranslate">
vim /etc/nginx/nginx.conf
</pre>
<pre class="brush: bash; highlight: [4,5,12,18,19,26]; title: ; notranslate">
# acá otras configuraciones
http {
  server {
    listen   80;
    server_name ejemplo1.com www.ejemplo1.com *.ejemplo1.com;

    location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_pass http://127.0.0.1:3000/;
         proxy_redirect off;
    }
  }

  server {
    listen   80;
    server_name ejemplo2.com www.ejemplo2.com *.ejemplo2.com;

    location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_pass http://127.0.0.1:3050/;
         proxy_redirect off;
    }
  }
}
</pre>
<p>Guardamos el config y arrancamos nginx</p>
<pre class="brush: bash; title: ; notranslate">
sudo service nginx start
</pre>
<p>Pueden ver un ejemplo de una configuración <a href="http://wiki.nginx.org/NginxFullExample">acá</a></p>
<p>Y listo!, ahora entramos a http://ejemplo1.com y nos levanta el servidor que tenemos en el puerto 3000 y si entramos a http://ejemplo2.com el del puerto 3050.</p>
<h3>Mas info.</h3>
<h4>NGINX (Inglés)</h4>
<ul>
<li><a href="http://wiki.nginx.org/Main">Wiki</a></li>
<li><a href="http://blog.martinfjordvald.com/2010/07/nginx-primer/">Intro</a></li>
<li><a href="http://blog.martinfjordvald.com/2012/08/understanding-the-nginx-configuration-inheritance-model/">Entendiendo el Modelo de Herencia</a></li>
<li><a href="http://blog.martinfjordvald.com/2011/02/nginx-primer-2-from-apache-to-nginx/">Diferencias con Apache</a></li>
<li><a href="http://wiki.nginx.org/WhyUseIt">Por qué deberías usarlo?</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/03/nodejs-a-la-nube-con-nginx-en-un-vps/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>AMD vs CJS</title>
		<link>http://fernetjs.com/2013/03/amd-vs-cjs/</link>
		<comments>http://fernetjs.com/2013/03/amd-vs-cjs/#comments</comments>
		<pubDate>Tue, 19 Mar 2013 12:34:07 +0000</pubDate>
		<dc:creator>Pablo Novas</dc:creator>
				<category><![CDATA[Client Side]]></category>
		<category><![CDATA[Server Side]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[amd]]></category>
		<category><![CDATA[asincronismo]]></category>
		<category><![CDATA[commonjs]]></category>
		<category><![CDATA[modulos]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3531</guid>
		<description><![CDATA[Uff, bueno, este tema da para debatir un largo rato, pero mi intento es mostrar mi investigación y una opción ... <br /><a class="more-link" href="http://fernetjs.com/2013/03/amd-vs-cjs/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Uff, bueno, este tema da para debatir un largo rato, pero mi intento es mostrar mi investigación y una opción que adopté para mis proyectos hoy por hoy.</p>
<p>Se acuerdan cuando hablaba de organizar el código de JS, que ya no es scripting y creación de funciones colgadas por todos lados, que a medida que la web crece y hacemos aplicaciones, en vez de una paginita web con botones ya creamos aplicaciones web. Un inicio por el camino correcto al orden es desacoplar creando módulos y hablaba de como hacerlo en el post <a href="http://fernetjs.com/2012/05/patrones-module-y-namespace/" title="Patrones: Module y Namespace">Patrones: Module y Namespace</a>.</p>
<p>Bueno, avanzando sobre ese tema, existen definiciones y estandares para crear y utilizar módulos, de eso se trata este post. Vamos a ver de que se trata cada uno de estos <em>enfoques</em> para solucionar el problema.</p>
<h3>AMD: Asynchronous Module Definition</h3>
<p>La <em>Definición Asíncrona de Módulos</em> fue creada para definir módulos donde este mismo y sus dependencias puedan ser cargadas asincrónicamente. Un ejemplo de esto es el conocido RequireJS (en este post muestro una intro: <a href="http://fernetjs.com/2012/02/requirejs-modulos-y-dependencias/" title="RequireJS: Módulos y Dependencias">RequireJS: Módulos y Dependencias</a>).<br />
Se puede decir que fue pensado especialmente para el Navegador donde es importante tener este tipo de asincronismo. También existen herramientas de optimización para el navegador donde es importante cargar lo necesario e indispensable mejorando la experiencia con nuestro sitio.</p>
<p>Demasiado texto, tiremos un poco de código para no dormirnos. <img src='http://fernetjs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: jscript; title: ; notranslate">

// define( [nombre] , [dependencias] , [definición]);

define('miModulo', ['otroModulo'], function(otroModulo){
  // listo, acá defino el módulo &quot;miModulo&quot;, 
  // porque la dependencia a otroModulo ya fue cargada y la tengo disponible.

  return {
    acceso: function(){ }
  };
});
</pre>
<p>De esta manera puedo definir cada módulo de mi aplicación con sus dependencias a otros módulos y me aseguro que todo existe antes de utilizarlos.</p>
<h3>CJS: Common JS</h3>
<p>Ahora cambia un poco la idea, en CJS no tenemos &#8220;definición de módulos&#8221;, es decir, no escribimos un &#8220;define&#8221;, sino que se asume que sus dependencias ya están cargadas al momento de requerirlas.<br />
Para este caso podemos decir que fue pensado para el Server (por ej. NodeJS), donde realizamos un <em>require([módulo])</em> y lo tenemos, sin asincronismo:</p>
<pre class="brush: jscript; title: ; notranslate">

//no hay ningún define()

var otroModulo = require('./otroModulo');

// acá va el código de nuestro módulo

module.exports.acceso = function() {};

</pre>
<p>Si bien, estamos de alguna manera definiendo sus dependencias con require(), la diferencia principal es que no lo hacemos antes de ejecutarse, es decir, podemos tener funciones y realizar esos require() desde cualquier parte del módulo, pero eso si, siempre se asume que ya está cargado.</p>
<h3>AMD + CJS</h3>
<p>Pero que pasa si intentamos utilizar el ejemplo anterior de CommonJS en el navegador?, definitivamente no va a funcionar.<br />
Así como tampoco utilzar un <em>define</em> en NodeJS.<br />
Entonces cual es mejor?, cuando?, donde?. Bueno, a mi parecer no hay uno mejor que el otro, ya explique para que fueron creados, ambos tienen sus pros y contras.</p>
<p>Mi problema, personal, es que me gusta AMD por su asincronismo, pero también me gusta CJS por el hecho de no definir dependencias y de poder utilizar mis módulos en NodeJS también (mientras no utilice DOM jeje), así que opté por utilizar ambos para el navegador.<br />
Como?, bueno ahí esta lo divertido, simplemente envolviendo cada módulo CJS en uno de AMD, pero en tiempo de &#8220;compilación&#8221; (*) (sino sería medio extraño), es decir, usando <a href="http://gruntjs.com/">GruntJS</a> con la ayuda de <a href="https://github.com/medikoo/modules-webmake">WebMake</a>.</p>
<blockquote><p>
(*) con &#8220;compilación&#8221; me refiero a la tarea en GruntJS, realmente no se esta &#8220;compilando&#8221; el javascript jaja.
</p></blockquote>
<p>En un futuro post voy a mostrar un poco mas de GruntJS, pero por el momento les dejo un proyecto base en Github sobre esto de AMD + CJS + GruntJS + WebMake (también tiene un poco de Backbone y Backbone Marionette <img src='http://fernetjs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p><a href="https://github.com/pjnovas/base-client-project">https://github.com/pjnovas/base-client-project</a> (les debo el Readme en Español)</p>
<hr/>
<h4>Cuál te gustas más? AMD o CJS?</h4>
<hr/>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/03/amd-vs-cjs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Detrás de escena: wrapper objects</title>
		<link>http://fernetjs.com/2013/03/detras-de-escena-wrapper-objects/</link>
		<comments>http://fernetjs.com/2013/03/detras-de-escena-wrapper-objects/#comments</comments>
		<pubDate>Fri, 08 Mar 2013 14:02:58 +0000</pubDate>
		<dc:creator>Matias Arriola</dc:creator>
				<category><![CDATA[Lenguaje]]></category>
		<category><![CDATA[tipos de datos]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3578</guid>
		<description><![CDATA[Muchas cosas de las que voy a compartir ahora, las aprendí hace relativamente poco y me permitieron entender algunos de ... <br /><a class="more-link" href="http://fernetjs.com/2013/03/detras-de-escena-wrapper-objects/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Muchas cosas de las que voy a compartir ahora, las aprendí hace relativamente poco y me permitieron entender algunos de los WTF que se ven en javascript. Creo que el típico <code>'string' vs. new String('string')</code> es uno de los conceptos que uno dá por sentado y nunca se cuestiona lo suficiente.</p>
<p>Cuando leí <a href="https://hacks.mozilla.org/2012/12/performance-with-javascript-string-objects/" title="Performance with javascript strings (inglés)" target="_blank">este artículo</a> que habla sobre la performance en objectos String, aparte de pensar &#8220;que bueno debe ser tener tiempo para hacer experimentos como esos&#8221;, me topé con la teoría detrás de los &#8216;wrapper objects&#8217;. De ahí, llegué a <a href="http://kiro.me/blog/wrapper_objects.html" title="wrapper objects en kiro.me (inglés)" target="_blank">este link</a> que me parece absolutamente recomendable (al igual que el resto del blog). Casi todo lo que escriba de acá en adelante, tal vez sea parafrasear o hablar un poco más de lo mismo que en esos enlaces.</p>
<blockquote><p>En JavaScript, los strings, los numeros, los booleanos, no son objetos; son tipos primitivos. Por consiguiente, no tienen propiedades. Es decir, &#8216;un string&#8217; no tiene ni indexOf, toUpperCase, ni length&#8230; Nada.
</p></blockquote>
<h3>¿Entonces?</h3>
<p>Después de leer eso, vale la pena abrir la consola de javascript, ¿ Por qué puedo hacer <code>'fernet'.concat('js')</code> ???</p>
<p>La respuesta es sencilla: por detrás, lo que ocurre es que el string &#8216;fernet&#8217; es automáticamente convertido a un objeto String, es decir a <code>new String('fernet')</code>, y ese objeto es el que tiene todas las propiedades y métodos que conocemos; por eso es posible aplicarle el <code>concat</code>.<br />
El método concat devuelve un string primitivo, aunque la misma conversión automática ocurriría si quisieramos utilizar alguna de sus propiedades.</p>
<pre class="brush: jscript; title: ; notranslate">
typeof 'fernet' // &quot;string&quot;
typeof 'fernet'.concat('js') // &quot;string&quot;
'fernet'.concat('js').toUpperCase() // &quot;FERNETJS&quot;
</pre>
<p>Vuelvo a insistir con lo mismo para aquellos que no acostumbren a hacerlo: experimentar con la consola js de las herramientas de desarrollo de su navegador favorito es una de las mejores maneras de aprender, descubrir nuevos conceptos, y reconfirmar las cosas que ya sabemos. </p>
<pre class="brush: jscript; title: ; notranslate">
var a = 'ejemplo',
    b = new String('ejemplo');

typeof a //&quot;string&quot;
typeof b //&quot;object&quot;
a == b //true
a === b //false
a + b //&quot;ejemploejemplo&quot;

// puedo consultar propiedades para ambos
a.length //7 (gracias a la conversión implícita a su wrapper obj) 
b.length //7
</pre>
<p>Por si sigue sonando extraño, esto sería lo que hace el intérprete de javascript &#8220;detrás de escena&#8221; cuando hacemos &#8216;FERNETJS&#8217;.toLowerCase():</p>
<pre class="brush: jscript; title: ; notranslate">
var stringOriginal = 'FERNETJS';
var str = new String(stringOriginal); //str sería el wrapper object 
str.toLowerCase(); // 'fernetjs'
</pre>
<p>El intérprete no sólo usa este &#8220;wrapper object&#8221; detrás de escena cuando queremos obtener una propiedad, sino que también cuando la queremos setear; pero esto puede ser contraproducente:</p>
<pre class="brush: jscript; title: ; notranslate">
var str = 'mmm';
str.unaPropiedadInventada = 100;
str.unaPropiedadInventada // undefined
var str2 = new String('jeje');
str2.unaPropiedadInventada = 100;
str2.unaPropiedadInventada //100
</pre>
<h3>Sobre la conversión [tipos primitivos]<->[wrappers]</code></h3>
<p>Nosotros podemos trabajar con tipos primitivos o con objetos, y podemos explícitamente hacer conversiones en ambas direcciones.</p>
<pre class="brush: jscript; title: ; notranslate">
// con new Number envolvemos al primitivo 1 en un objeto number
var n = new Number(1);
typeof n //&quot;object&quot;
// llamando a Number (sin new) convierte el obj a su primitivo
typeof Number(n) //&quot;number&quot;
</pre>
<p>De todas maneras, no es recomendable y rara vez o nunca, vamos a escribir en nuestro código <code>var x = new Number(17)</code>. La principal razón, es que no nos va a ser de gran utilidad, ya que sea cual sea el valor del objeto, siempre va a ser "verdadero" en el resultado de una evaluación:</p>
<pre class="brush: jscript; title: ; notranslate">
var tengoPlata = new Boolean(false);
if (tengoPlata)
    console.log('comprar unos fernecitos');
else 
    console.log('esperar');
</pre>
<p>En el caso anterior, por ejemplo, quería decir que no tenía plata. De todas maneras, se ejecuta "comprar unos fernecitos", dejándome en bancarrota. Esto ocurre porque tengoPlata es un objeto, en contraste con el <code>false</code> que hubiera sido más natural usar.</p>
<p>Por otra parte, desde objeto hacia tipo primitivo muchas veces se hacen conversiones automáticas, (del mismo modo que 1 podría ser convertido a '1'), más que nada a la hora de operar.<br />
Por ejemplo:</p>
<pre class="brush: jscript; title: ; notranslate">
var x = new Number(199),
    y = 1;
x + y // 200
</pre>
<p>Estas conversiones se basan en lo que devuelve el valueOf() del objeto. Es decir, siempre que se trate de convertir un objeto a un primitivo, el resultado de la conversión va a ser lo que devuelve el valueOf. Este método está en todos los objetos, y si no es sobreescrito, va a devolver el mismo objeto (<a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/valueOf" title="valueOf en MDN" target="_blank">docs de valueOf</a>).<br />
Lo más loco de este artículo es lo que sigue. Sabiendo esto, uno podría emular un objeto, que al momento de operar sería convertido a su correspondiente valor primitivo.</p>
<pre class="brush: jscript; title: ; notranslate">
var a = {
  valueOf: function(){ return 199; }
};
console.log(a + 1); //200

var b = { 
    valueOf: function(){ return navigator.plugins.length; } 
};
console.log(b - 1); //???? jeje
</pre>
<h3>¿De qué me sirve saber esto?¿Ya puedo hacer juegos multiplayer en 4-D con js?</h3>
<p>La verdad que al fin y al cabo todo esto no tiene mucho sentido práctico, uno podría vivir sin saberlo, pero ayuda a conocer un poco más el lenguaje y entender por qué las cosas funcionan de la manera que lo hacen.<br />
Sí es importante tener presente los problemas que puede traer manualmente instanciar estos objetos String, Number, etc.. </p>
<p>NOTAS: * A lo largo de todo el artículo se utilizó el termino 'wrapper object'. Esto se debe a que no encontré una traducción acorde, 'objeto envolvedor', 'objeto envoltorio' simplemente no sonaban correctos. Sugerencias?<br />
* Cuando se habla de String, Number, Boolean en los ejemplos, la mayoría de las veces se podrían haber aplicado indistintamente. </p>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/03/detras-de-escena-wrapper-objects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Curry</title>
		<link>http://fernetjs.com/2013/03/curry/</link>
		<comments>http://fernetjs.com/2013/03/curry/#comments</comments>
		<pubDate>Wed, 06 Mar 2013 12:49:06 +0000</pubDate>
		<dc:creator>Pablo Benito</dc:creator>
				<category><![CDATA[Lenguaje]]></category>
		<category><![CDATA[curry]]></category>
		<category><![CDATA[funciones]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3493</guid>
		<description><![CDATA[Intro Para contarles que es Curry me voy a basar en el libro   &#8220;JavaScript Patterns &#8211; Stoyan Stefanov&#8220;. ( ... <br /><a class="more-link" href="http://fernetjs.com/2013/03/curry/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<h3>Intro</h3>
<p>Para contarles que es Curry me voy a basar en el libro   &#8220;<a href="http://www.amazon.es/JavaScript-Patterns-Stoyan-Stefanov/dp/3897215985/ref=sr_1_2?s=foreign-books&#038;ie=UTF8&#038;qid=1362573485&#038;sr=1-2">JavaScript Patterns &#8211; Stoyan Stefanov</a>&#8220;. ( Lo pueden comprar en su librería de confianza <img src='http://fernetjs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>
<p>En <a href="http://en.wikipedia.org/wiki/Currying">este link</a> tienen una def un poco más genérica, desatada del mundo JS.</p>
<p><em>&#8220;Curry es una técnica de transformación de funciones que permite obtener a partir de una función A otra B que es la versión <strong>parcialmente aplicada de A</strong>.&#8221;</em> Después de la teoría vienen un par de formas de hacerlo con JavaScript.</p>
<h3>Que es una aplicación y una aplicación parcial?</h3>
<p>Podemos tomar con fines prácticos hablando en un contexto menos matemático y mas JS que una aplicación es como una llamada a función y que aplicar parcialmente una función es llamarla con no todos los argumentos esperados sino con algunos de los primeros. Como de esta forma no podemos obtener el resultado final que obtendríamos de pasarle todos los parámetros, lo que se obtiene es una función que se puede llamar con los parámetros restantes y devolver el resultado como si hubiese sido llamada con todos los parámetros.</p>
<h3>Implementaciones</h3>
<h4>Curry manual:</h4>
<pre class="brush: jscript; title: ; notranslate">
function sumar( x, y ) {
    if ( typeof y === 'undefined' ) { //detección de aplicación parcial
        return function ( y ) { //la transformación ( curring )
            return x + y;
        };
    } else {
        return x + y;//aplicación completa
    }
}

var sumaParcial = sumar( 4 );// Obtener suma parcialmente aplicada, memoriza x

var result = sumaParcial( 5 ); // uso de la versión parcialmente aplicada, el 5 se usa para y que al sumarle la x memorizada ( 4 ) dará como resultado 9. 

//También lo podemos usar así:
var result2 = sumar( 4 ) ( 5 );
</pre>
<p>En esta implementación del curry, la aplicación parcial está en la misma función sumar, si vamos a usar mucho esta técnica, se puede hacer una forma más versátil que pueda aplicar curry a cualquier función que querramos en el libro aparece el ejemplo, la función schonfinkelize de 7 lineas que le pone curry a lo que se le cruce:</p>
<h4>Curry pro</h4>
<pre class="brush: jscript; title: ; notranslate">
function schonfinkelize(fn) {
   var slice = Array.prototype.slice,
     stored_args = slice.call(arguments, 1);
   return function () {
      var new_args = slice.call(arguments),
         args = stored_args.concat(new_args);
      return fn.apply(null, args);
   };
}

//Ejemplo de uso:
// Función a modificar:
function echo( x ) {
  return x;
}

// Función modificada
var elephantFunction = schonfinkelize( echo, 'algo para recordar' );//La Transformación ( curring )

// Aplicación, en un objeto mock, o un objeto que necesita tener un método que devuelva siempre el mismo valor con fines de polimorfimo
var mock = {
   getMessage: elephantFunction
}
</pre>
<blockquote><p>
Mas info sobre apply en <a href="http://fernetjs.com/2012/01/patrones-de-invocacion-de-funciones-this/" title="Patrones de Invocación de Funciones: this">Patrones de Invocación de Funciones: this</a> y en <a href="http://fernetjs.com/2013/01/modificando-el-contexto-call-apply-y-bind/" title="Modificando el contexto: call, apply y bind">Modificando el contexto: call, apply y bind</a>
</p></blockquote>
<h4>Implementación de Underscore.js</h4>
<p><a href="http://underscorejs.org" target="_blank">Underscore</a> viene con<strong> la función partial</strong> que permite hacer las partial applications, el ejemplo anterior, hecho con esta funcionalidad de underscore sería :</p>
<pre class="brush: jscript; title: ; notranslate">
var mock = {
   getMessage: _.partial( echo, 'algo para recordar' ) //La transformación ( curring )
}
</pre>
<h3>Ejemplos de Uso:</h3>
<p>Imagínense que tenemos una función densidad de tres variables de entrada ( x, y , z ) que nos devuelve la concentración de algo ( un compuesto por ejemplo ) en un cuerpo dado. Densidad podría tener información de una tomografía computada o de un examen de resonancia magnética nuclear, x podría representar la dimensión longitudinal de pies a cabeza, y con _.partial( densidad, 3 ), podríamos obtener un corte ( una imagen ) de esa información a 3 centímetros de la planta de los pies.</p>
<p>Ok, que pasa si se nos fué la mano con el fernet y queremos cortes que no sean perpendiculares a ninguno de los ejes xyz? Rta, tendríamos que aplicar un poco (bastante) de matemática, como para obtener una función similar partial, pero que se llame por ejemplo slice que reciba como entrada un vector con un punto por donde debe pasar el corte y otro perpendicular al plano de corte, ejemplo:  corte = _.slice( [3, 0, 0], [0, 0, 1], densidad ) // el corte pasa por x = 3 y el vector normal es el que tiene solo componente z.   La función devuelta tendría dos variables de entrada, que serían coordenadas x y y en el plano de corte ( que no necesariamente son las mismas que las originales).</p>
<p>Bueno, espero que les haya gustado.</p>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/03/curry/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mongoose + Nodejs + Modelos! Parte 1</title>
		<link>http://fernetjs.com/2013/02/mongoose-nodejs-modelos-parte-1/</link>
		<comments>http://fernetjs.com/2013/02/mongoose-nodejs-modelos-parte-1/#comments</comments>
		<pubDate>Wed, 13 Feb 2013 13:35:05 +0000</pubDate>
		<dc:creator>alejonext</dc:creator>
				<category><![CDATA[Bibliotecas]]></category>
		<category><![CDATA[Server Side]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mongoose]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3516</guid>
		<description><![CDATA[La verdad es genial las NoSQL, pero siempre existe el problema. Como se modelar toda la información, tanto en NoSQL ... <br /><a class="more-link" href="http://fernetjs.com/2013/02/mongoose-nodejs-modelos-parte-1/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>La verdad es genial las NoSQL, pero siempre existe el problema. Como se modelar toda la información, tanto en NoSQL como en SQL. Como todos buenos arquitectos de la información, pero en este caso vamos a utilizar el FarmeWork <a href="http://mongoosejs.com" title="MongooseJs">MongooseJs</a> que corre bastante bien en NodeJs.</p>
<p>Todo comenzó con los <code>callbacks</code>, en el <code>mongodb-native</code> de NodeJS. La verdad es bastante estresante generar muchísimos <code>callbacks</code>, y no se pueden generar relaciones entre una y otra colección. Ese realmente fue el problema que me enfrente. Y buscando encontré <a href="http://mongoosejs.com" title="MongooseJs">MongooseJs</a>, que construye modelos de información, para que todo sea mas asequible, y mas fácil de encontrar. Vamos a echarle un vistazo!</p>
<pre class="brush: jscript; title: ; notranslate">
var mongoose = require('mongoose');
var db = mongoose.createConnection( 'mongodb://localhost:27017/prueba' );
</pre>
<p>Hasta hora no es nada raro! Solo llamamos el modulo y le construimos una conexión a la base de datos. Ahora bien lo interesante! La construcción de la base de datos</p>
<pre class="brush: jscript; title: ; notranslate">
var postSchema = mongoose.Schema({
    titulo: { type : String, trim : true, index : true },
    post : string,
    slug : string,
    autor : { type : Schema.Types.ObjectId, ref : 'autores' }  });
var userSchema = mongoose.Schema({
    name : { type : String, trim : true },
    nick : { type : String, trim : true, index : true },
    email: { type : String, trim : true },
});
</pre>
<p>Listo! voy a dar un ejemplo de blog! Como vemos, construimos Schema (Esquemas). Estos esquemas, es tan dados en Json (Bastante cercano a MongoDB por que utilizan BSON que es el mismo JSON pero en Binario ). Cada propiedad debe tener una definición, al igual se pueden colocar múltiples validaciones de esa propiedad. Y todas los valores van a ser validados, si existe algún error nos mostrara. Es decir a los <code>titulo</code> no le puedo poner un <code>false,</code> únicamente un <code>String</code>.</p>
<pre class="brush: jscript; title: ; notranslate">
var Post = db.model('posts', postSchema);
var User = db.model('users', userSchema);
</pre>
<p>Y en lazaremos con la base de datos. El primer parámetro es el nombre de la Colección, y el segundo parámetro es el esquema. Ya con esto podemos subir información a la base de datos. Claro en el momento de subida va hacer validada.</p>
<pre class="brush: jscript; title: ; notranslate">
var PrimerUsuario =  new User({
    name : 'Pepito Perez',
    nick : 'pepito',
    email: 'pepito@pepito.com'
});
PrimerUsuario.save(function(err, doc){
   if(err)
      console.log(err);
   var PrimerPost = new Post({
       titulo: 'Este es mi primer Post!',
       post  : 'Publicando mi primer post!! que felicidad!!',
       autor : doc._id,
   });
   PrimerPost.slug = slug( PrimerPost.titulo );
   PrimerPost.save( function(err, doc){
     console.log(err);
     console.log(doc);
   })
});
</pre>
<p>Como podemos ver, lo primero que llamamos es a la creación de un nuevo usuario, le montamos en las propiedades que queremos, al igual que un <code>prototype</code>. Y claro esta la función llamada <code>save</code>, que nos va a retornar el Error y el Documento. Generando un nuevo post, hacemos lo mismo es decir le pasamos los parámetros que queremos. Yo utilizo <code>Slug</code> para tener urls familiares, al igual es un <code>Object</code>. Y guardamos! Y veremos algo así en consola.</p>
<pre class="brush: jscript; title: ; notranslate">
{
    _id : 50903550a04313310c000001,
    titulo : 'Este es mi primer Post!',
    post : 'Publicando mi primer post!! que felicidad!!',
    slug : 'este-es-mi-primer-post',
    autor : 2d2ac97cf59cee65f7a38e596c,
}
</pre>
<p>Claro yo se que los <code>id</code> no son los mismos, que salen en tu consola. Pero seamos un poco desconfiados, vamos a revisar la base de datos!</p>
<pre class="brush: jscript; title: ; notranslate">
$ mongo
mongo&gt; show dbs
prueba 0.203125GB
test 0.203125GB
mongo&gt; use prueba
mongo&gt; show collections
posts
users
mongo&gt; db.users.find()
{ &quot;_id&quot; : ObjectId(&quot;2d2ac97cf59cee65f7a38e596c&quot;), &quot;name&quot; : &quot;Pepito Perez&quot;, &quot;nick&quot; : &quot;pepito&quot;, &quot;email&quot; : &quot;pepito@pepito.com&quot; }
mongo&gt; db.posts.find()
{ _id : ObjectId(&quot;50903550a04313310c000001&quot;), &quot;titulo&quot; : &quot;Este es mi primer Post!&quot;, &quot;post&quot; : &quot;Publicando mi primer post!! que felicidad!!&quot;, &quot;slug&quot; : &quot;este-es-mi-primer-post&quot;, &quot;autor&quot; : ObjectId(&quot;2d2ac97cf59cee65f7a38e596c&quot; }
</pre>
<p>Genial!! Esta toda la información que subimos a la base de datos. Vamos a buscar a nuestro usuario!</p>
<pre class="brush: jscript; title: ; notranslate">
User.findOne().where('nick', 'pepito').exec(function(err, doc){
   console.log(err);
   console.log(doc);
});
</pre>
<pre class="brush: jscript; title: ; notranslate">
null
{
    _id : 2d2ac97cf59cee65f7a38e596c,
    name : &quot;Pepito Perez&quot;,
    nick : &quot;pepito&quot;,
    email : &quot;pepito@pepito.com&quot;,
}
</pre>
<p>Tomamos el modelo, y le mandamos un <code>findOne</code>, <code>find</code> o <code>findById</code>, le podremos pasar <a title="Querys de MongoDB" href="http://docs.mongodb.org/manual/reference/operators/">querys de Mongodb</a>. Pero todos estos parámetros en una función como aquí, y nos facilitan el trabajo. Nunca olvidemos hacerle <code>exec</code>. Si al igual podemos buscar los <code>Post</code>, pero también podemos saber de que usuario es! Miremos como se hace</p>
<pre class="brush: jscript; title: ; notranslate">
Post.find().populate('autor').exec(function(err, doc){
   console.log(err);
   console.log(doc);
});
</pre>
<p>Bueno en este caso, buscamos todos los Post. Le montamos la función <code>populate</code>, lo que hace, es buscar según el <code>id</code>, en otra colección y lo anida en la propiedad <code>autor</code>. Miremos que nos muestra la consola!</p>
<pre class="brush: jscript; title: ; notranslate">
null
[ {
    _id : 50903550a04313310c000001,
    titulo : 'Este es mi primer Post!',
    post : 'Publicando mi primer post!! que felicidad!!',
    slug : 'este-es-mi-primer-post',
    autor : {
        _id : 2d2ac97cf59cee65f7a38e596c,
        name : &quot;Pepito Perez&quot;,
        nick : &quot;pepito&quot;,
        email : &quot;pepito@pepito.com&quot;,
    }
} ]
</pre>
<p>Como nos damos cuenta, es un <code>Array</code> o mejor una lista de <code>Object</code>, y dentro de cada <code>Object</code> existe el <code>Object</code> Usuario. Así se vuelve mucho mas fácil tanto la búsqueda como la subida de información. Claro teniendo esto podemos modificar el <code>nick</code> de nuestro usuario y con un <code>.save</code>, se sube a la base de datos.</p>
<p>Bueno esta es la primera parte de esta serie de posts. En el próximo les mostrare como guardar elementos anidados, hacer querys avanzados y validaciones.</p>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/02/mongoose-nodejs-modelos-parte-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Modificando el contexto: call, apply y bind</title>
		<link>http://fernetjs.com/2013/01/modificando-el-contexto-call-apply-y-bind/</link>
		<comments>http://fernetjs.com/2013/01/modificando-el-contexto-call-apply-y-bind/#comments</comments>
		<pubDate>Fri, 25 Jan 2013 20:36:53 +0000</pubDate>
		<dc:creator>Pablo Novas</dc:creator>
				<category><![CDATA[Lenguaje]]></category>
		<category><![CDATA[apply]]></category>
		<category><![CDATA[argumentos]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[call]]></category>
		<category><![CDATA[funciones]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3500</guid>
		<description><![CDATA[Buenas!, hace muy poquito conocí el bind() y me dieron ganas de armar un post mostrando la diferencia entre los ... <br /><a class="more-link" href="http://fernetjs.com/2013/01/modificando-el-contexto-call-apply-y-bind/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Buenas!, hace muy poquito conocí el bind() y me dieron ganas de armar un post mostrando la diferencia entre los 3.</p>
<p>Antes de arrancar, te recomiendo que leas el post <a href="http://fernetjs.com/2012/01/patrones-de-invocacion-de-funciones-this/" title="Patrones de Invocación de Funciones: this">Patrones de Invocación de Funciones</a> que habla sobre el bindeo del contexto en el famoso <em>this</em>, así puedo concentrarme en mostrarte la diferencia entre estos métodos.</p>
<p>Bueno, ahora que sabes esto del <em>this</em> y como se bindea su contexto, algo que es extremadamente útil a la hora de tener el control sobre las funciones o métodos que hacemos y utilizamos.</p>
<p>Como viste en el post mas arriba en el caso del <em>apply</em> lo que estamos haciendo es meterle un nuevo contexto a una función, por ejemplo:</p>
<pre class="brush: jscript; title: ; notranslate">
var obj = {
  delta: 2,
  test: function(num1, num2){
     return (num1 + num2) * this.delta;
  }
};

var resultado = obj.test(2,2);
console.log(resultado); // (2 + 2) * 2 = 8
</pre>
<p>En este caso, simplemente tenemos un objeto con una propiedad y una función, al llamarla con 2 números, los sumamos y le aplicamos el delta de su contexto (en el cual está corriendo la función), que para este caso es el objeto en si mismo.</p>
<p>Pero que pasa si ahora queremos cambiarle ese contexto, un nuevo delta, definido por nosotros pero sin modificar el objeto&#8230;</p>
<h3>apply()</h3>
<pre class="brush: jscript; title: ; notranslate">
var cambio = {
  delta: 5
};

var resultado = obj.test.apply(cambio, [2,2]);
console.log(resultado); // (2 + 2) * 5 = 20
</pre>
<p>Le aplicamos un nuevo contexto en el cual corre la función, por lo que ahora el <em>this</em> de <em>obj</em> va a contenter nuestro objeto <em>cambio</em>, por ende, el delta valdrá 5 al ejecutarse.<br />
Y que es el array que sigue a la llamada?, esos son los argumentos que recibe la función:</p>
<pre class="brush: jscript; title: ; notranslate">
  [funcion].apply([contexto], [parámetros como array]);
</pre>
<h3>call()</h3>
<p>Otra forma de llamar a una función aplicandole un contexto es con <em>call</em>, siguiendo con el ejemplo del apply:</p>
<pre class="brush: jscript; title: ; notranslate">
var cambio = {
  delta: 5
};

var resultado = obj.test.call(cambio, 2, 2);
console.log(resultado); // (2 + 2) * 5 = 20
</pre>
<p>La única diferencia es la forma de pasar los argumentos, ya que en vez de que sea un array, simplemente toma el primero como el contexto y los siguientes son los argumentos en el orden que los esperamos.</p>
<pre class="brush: jscript; title: ; notranslate">
  [funcion].call([contexto], [param1], [param2], [paramN]);
</pre>
<h3>bind()</h3>
<p>En este caso hay una vuelta de tuerca mas, que nos puede ser bastante útil.<br />
El <em>bind()</em> no llama a la función con un nuevo contexto, sino que nos devuelve una referencia a la función con ese nuevo contexto:</p>
<pre class="brush: jscript; title: ; notranslate">
var cambio = {
  delta: 5
};

var funcionConCambio = obj.test.bind(cambio);
var resultado = functionConCambio(2, 2);
console.log(resultado); // (2 + 2) * 5 = 20
</pre>
<p>Muy loco!, esto aplicado a callbacks puede ser muy interesante.<br />
Usas el <em>self</em>, <em>me</em> o <em>that</em>?</p>
<p>Supongamos tenemos una llamada ajax y definimos un callback para cuando termina, un ejemplo común sería:</p>
<pre class="brush: jscript; title: ; notranslate">
// más código donde utilizamos el this
var that = this;
function callback(datos){
  that.magia(datos);
}

ajax(callback);
</pre>
<p>Ahora con bind nos quedaría asi:</p>
<pre class="brush: jscript; title: ; notranslate">
function callback(datos){
  this.magia(datos);
}

ajax(callback.bind(this));
</pre>
<p>Mucho más limpio!</p>
<blockquote><p>
Algo a tener en cuenta es que el metodo bind() aparece en el ECMAScript 5ta Edición, por lo que puede que los navegadores ancianitos no lo soporten.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2013/01/modificando-el-contexto-call-apply-y-bind/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Almacenando en el cliente: LocalStorage, SessionStorage y Cookies</title>
		<link>http://fernetjs.com/2012/12/almacenando-en-el-cliente-localstorage-sessionstorage-y-cookies/</link>
		<comments>http://fernetjs.com/2012/12/almacenando-en-el-cliente-localstorage-sessionstorage-y-cookies/#comments</comments>
		<pubDate>Thu, 20 Dec 2012 13:15:50 +0000</pubDate>
		<dc:creator>Pablo Novas</dc:creator>
				<category><![CDATA[Client Side]]></category>
		<category><![CDATA[Utilidades]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[local storage]]></category>
		<category><![CDATA[session storage]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3318</guid>
		<description><![CDATA[Seguramente ya escuchaste sobre el almacenamiento local de HTML5, la intensión de este post es pegarle un vistazo para que ... <br /><a class="more-link" href="http://fernetjs.com/2012/12/almacenando-en-el-cliente-localstorage-sessionstorage-y-cookies/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Seguramente ya escuchaste sobre el almacenamiento local de HTML5, la intensión de este post es pegarle un vistazo para que empieces a usarlo.</p>
<p>Primero tenemos que tener en cuenta que LocalStorage es el almacenamiento que no expira, y SessionStorage es el que vive sólo en una sesión.<br />
Ambos tienen los mismos métodos:</p>
<ul>
<li><strong>getItem</strong> ( <em>key</em> )</li>
<li><strong>setItem</strong> ( <em>key</em> , <em>value</em> )</li>
<li><strong>removeItem</strong> ( <em>key</em> )</li>
</ul>
<blockquote><p>
Van a ver por ahí un <strong>globalStorage</strong>: es una implementación de Mozilla previa a HTML5, pero desde la versión de Firefox 13 dejó de soportarse, por lo que olvidate de que existe <img src='http://fernetjs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
</p></blockquote>
<p>No hay mucho para explicar sobre los métodos ya que hablan por si solos, veamos un ejemplo:</p>
<pre class="brush: jscript; title: ; notranslate">
if (window.localStorage) {

  localStorage.setItem(&quot;nombre&quot;, &quot;pepe&quot;);

  var nombre = localStorage.getItem(&quot;nombre&quot;);
  
  localStorage.removeItem(&quot;nombre&quot;);
}
else {
  throw new Error('Tu Browser no soporta LocalStorage!');
}
</pre>
<blockquote><p>
También se puede utilizar los Items como propiedades del objeto localStorage ó sessionStorage (pero <font style="color:red"><strong>no está recomendado</strong></font>, así que tomalo como título informativo):</p>
<pre class="brush: jscript; title: ; notranslate">
localStorage[&quot;nombre&quot;] = &quot;pepe&quot;;
var nombre = localStorage.nombre;
delete localStorage[&quot;nombre&quot;];
</pre>
</blockquote>
<p>El soporte de navegadores es muy amplio:</p>
<pre>
+----------------+--------+-----------------+----+-------+-----------------+
|    Feature     | Chrome | Firefox (Gecko) | IE | Opera | Safari (WebKit) |
+----------------+--------+-----------------+----+-------+-----------------+
| localStorage   |      4 | 3.5             |  8 | 10.50 |               4 |
| sessionStorage |      5 | 2               |  8 | 10.50 |               4 |
+----------------+--------+-----------------+----+-------+-----------------+
</pre>
<p>Pueden ver mas info <a href="http://caniuse.com/#feat=namevalue-storage">acá</a></p>
<p><strong>Y cuánto podemos almacenar?</strong>: depende mucho del navegador, pero la cantidad oscila entre 2.5 y 5 Mb (2.5 Mb en la mayoría de los navegadores, lo cual es bastante <img src='http://fernetjs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )<br />
Pueden ver la tabla completa y probar cuanto se banca el navegador en el que están en <a href="http://dev-test.nemikor.com/web-storage/support-test/">Web Storage Test</a></p>
<p><strong>Podemos guardar JSON?</strong>, Si, pero yo te recomendaria que sea serializado, (en String) y lo que hagas <strong>antes de enviarlo</strong>.<br />
Por que esto?</p>
<ol>
<li>Por los <em>&#8220;fallbacks/ polyfills&#8221;</em>, si queremos agregarle un soporte a cookies por si no tiene disponible el web storage, puede que tengamos problemas si no estamos manejando strings.</li>
<li>Lo serializa de todas formas, pero la diferencia es que no es automático, por lo que podemos tener comportamientos extraños:</li>
</ol>
<pre class="brush: jscript; title: ; notranslate">
  localStorage.setItem(&quot;locura&quot;, true);
  var locura = localStorage.getItem(&quot;locura&quot;);
  console.log(locura); // true
  console.log(typeof locura); // 'string'
</pre>
<p>Ahora, con JSON?, supongamos que tenemos:</p>
<pre class="brush: jscript; title: ; notranslate">
var persona = {
    nombre: &quot;pepe&quot;,
    edad: 20,
    locura: true
};
</pre>
<p><strong>Guardamos directo el JSON al localStorage:</strong></p>
<pre class="brush: jscript; title: Problem?; notranslate">
localStorage.setItem(&quot;persona&quot;, persona);
var personaGuardada = localStorage.getItem(&quot;persona&quot;);

console.log(typeof persona); //object
console.log(typeof personaGuardada); //string

console.log(personaGuardada.locura); //undefined!
var personaGuardada = JSON.parse(personaGuardada); //Uncaught SyntaxError
</pre>
<p><strong>Como habría que hacerlo:</strong></p>
<pre class="brush: jscript; highlight: [1,9]; title: ; notranslate">
var personaAGuardar = JSON.stringify(persona);

localStorage.setItem(&quot;persona&quot;, personaAGuardar);
var personaGuardada = localStorage.getItem(&quot;persona&quot;);

console.log(typeof persona); //object
console.log(typeof personaGuardada); //string

var personaGuardada = JSON.parse(personaGuardada); 
console.log(personaGuardada.locura); //true
</pre>
<hr/>
<p>Por último te dejo un fallback a Cookies, ya que no siempre tenemos soporte para usarlo, está es una implementacion de Mozilla bastante coqueta (no se si funciona en IE 7, por ejemplo), la idea es que en nuestra aplicación usamos directamente window.localStorage y siempre va a existir, si el browser no lo soporta va a ir a cookies automáticamente.<br />
<strong>Fuente</strong>: <a href="https://developer.mozilla.org/en-US/docs/DOM/Storage">MDN &#8211; DOM Storage</a></p>
<pre class="brush: jscript; title: ; notranslate">
if (!window.localStorage) {
  Object.defineProperty(window, &quot;localStorage&quot;, new (function () {
    var aKeys = [], oStorage = {};
    Object.defineProperty(oStorage, &quot;getItem&quot;, {
      value: function (sKey) { return sKey ? this[sKey] : null; },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, &quot;key&quot;, {
      value: function (nKeyId) { return aKeys[nKeyId]; },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, &quot;setItem&quot;, {
      value: function (sKey, sValue) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + &quot;=&quot; + escape(sValue) + &quot;; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/&quot;;
      },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, &quot;length&quot;, {
      get: function () { return aKeys.length; },
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, &quot;removeItem&quot;, {
      value: function (sKey) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + &quot;=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/&quot;;
      },
      writable: false,
      configurable: false,
      enumerable: false
    });
    this.get = function () {
      var iThisIndx;
      for (var sKey in oStorage) {
        iThisIndx = aKeys.indexOf(sKey);
        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
        else { aKeys.splice(iThisIndx, 1); }
        delete oStorage[sKey];
      }
      for (aKeys; aKeys.length &gt; 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
      for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx &lt; aCouples.length; nIdx++) {
        aCouple = aCouples[nIdx].split(/\s*=\s*/);
        if (aCouple.length &gt; 1) {
          oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]);
          aKeys.push(iKey);
        }
      }
      return oStorage;
    };
    this.configurable = false;
    this.enumerable = true;
  })());
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2012/12/almacenando-en-el-cliente-localstorage-sessionstorage-y-cookies/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Manejando Errores</title>
		<link>http://fernetjs.com/2012/12/manejando-errores/</link>
		<comments>http://fernetjs.com/2012/12/manejando-errores/#comments</comments>
		<pubDate>Wed, 12 Dec 2012 13:26:04 +0000</pubDate>
		<dc:creator>Pablo Novas</dc:creator>
				<category><![CDATA[Client Side]]></category>
		<category><![CDATA[Lenguaje]]></category>
		<category><![CDATA[Server Side]]></category>
		<category><![CDATA[argumentos]]></category>
		<category><![CDATA[asincronismo]]></category>
		<category><![CDATA[Error]]></category>
		<category><![CDATA[funciones]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[parámetros]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3149</guid>
		<description><![CDATA[Algo necesario en todo lenguaje de programación es el manejo de errores. Lamentablemente en JS es poco usado y en ... <br /><a class="more-link" href="http://fernetjs.com/2012/12/manejando-errores/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Algo necesario en todo lenguaje de programación es el manejo de errores. Lamentablemente en JS es poco usado y en llamadas asíncronas está mal usado la mayoría de las veces. Es por eso que armo este post para que nos enteremos de que el objeto Error existe en JS y nos sirve mucho mas de lo que sabemos y/o creemos.</p>
<p>Arrancamos con un ejemplo común:</p>
<pre class="brush: jscript; title: ; notranslate">
try {
  //.. venimos haciendo cosas 
  throw &quot;disparo un error!&quot;;
}
catch(e){
  console.log(e); // &quot;disparo un error!&quot;
}
</pre>
<p>Bueno, tiramos un error que es un string, pero podemos hacerlo mejor:</p>
<pre class="brush: jscript; title: ; notranslate">
try {
  //.. venimos haciendo cosas 
  throw new Error(&quot;disparo un error!&quot;);
}
catch(e){
  console.log(e.message); //&quot;disparo un error!&quot;
  console.log(e.stack); //Error: disparo un error! at http://localhost/:3:2 at condition .... 
}
</pre>
<p>Ahh, ahora se vé mucho mejor, tenemos el stack y el mensaje por separado y si hacemos un <em>throw e;</em> vamos a ver el error completito en la consola (o en el terminal en el caso de NodeJS). O sea, que ahora es un objeto, no mas cadenas voladas en el <em>eter</em>.</p>
<blockquote><p>
Cómo vimos en <a href="http://fernetjs.com/2011/10/alcance-de-variables-var-scope/" title="Alcance de Variables (var scope)">otro post</a>, el alcance de las variables es a nivel de función, pero para el catch, nuestra variable e tiene alcance SOLO dentro del catch:</p>
<pre class="brush: jscript; title: ; notranslate">
console.dir(e); //error: e no está declarada
catch(e){
  console.dir(e); //jeje   
}
console.dir(e); //error: e no está declarada
</pre>
</blockquote>
<p>Manejar errores de esta manera nos trae muchas facilidades, aparte de tener el Stack y de tener realmente una Excepcion y no un string, nos abre las puertas para empezar a manejar errores enserio, ahora podemos:</p>
<h3>Crear nuestros Tipos de Errores:</h3>
<pre class="brush: jscript; highlight: [5,6]; title: ; notranslate">
function MiError(mensaje) {
  this.name = &quot;MiError&quot;;
  this.message = mensaje || &quot;No Especificado&quot;;
}
MiError.prototype = new Error();
MiError.prototype.constructor = MiError;
 
try {
  throw new MiError(&quot;explotó!&quot;);
} catch (e) {
  console.log(e.name);     // &quot;MiError&quot;
  console.log(e.message);  // &quot;explotó&quot;
  console.log(e.stack);  // Error: explotó! at http://localhost/:9:2 at condition .... 
  console.log(e instanceof MiError); //true
}
</pre>
<p>Simplemente extendemos la clase <em>Error</em> con nuestro nuevo tipo de error <img src='http://fernetjs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Al tener tipos propios de errores, es seguro que vamos a necesitar catchear cada tipo, porque para eso los creamos, ya que esto no es un feo string y ahora es una clase, podemos comprobar por instancia para que quede prolijo:</p>
<pre class="brush: jscript; highlight: [4]; title: ; notranslate">
try {
  throw new MiError(&quot;explotó!&quot;);
} catch (e) {
  if (e instanceof MiError){
    console.log('fue MiError');
  }
  else {
    console.log('fue otra cosa así que disparo un error no manejado');
    throw e;
  }
}
</pre>
<blockquote><p>
Van a ver por ahí casos donde se utiliza:
<pre class="brush: jscript; title: ; notranslate">catch(e if e instanceof MiError)</pre>
<p> Cuidado con eso porque solo lo soporta Mozilla y no es parte del Standard ECMAScript.
</p></blockquote>
<p>Aparte del <em>coqueto</em> Error (piénsenlo como la clase <em>Exception</em> de C# o Java, sería el error más genérico), también tenemos otras Excepciones ya definidas que heredan de Error: </p>
<ul>
<li>EvalError</li>
<li>RangeError</li>
<li>ReferenceError</li>
<li>SyntaxError</li>
<li>TypeError</li>
<li>URIError</li>
</ul>
<blockquote><p>
Todo este manejo de errores funciona tanto en el cliente, como en el servidor con NodeJS. Lo que hay que tener en cuenta es que algunos navegadores ancianos no soportan la clase Error, pero hablamos de navegadores muy ancianos.</p>
<p>Para el cliente también hay otros tipos de excepciones ya definidas por ejemplo <strong>DOMExceptions</strong> (este va a depender de los niveles de DOM y del navegador, pero va para otro post <img src='http://fernetjs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )
</p></blockquote>
<h3>Manejando errores en Callbacks</h3>
<p>Ahora bien, tenemos otro caso de manejo de errores, los famosos y amados <a href="http://fernetjs.com/2011/12/creando-y-utilizando-callbacks/" title="Creando y utilizando callbacks">callbacks</a>, como manejaríamos los errores?, tenemos un tema, no deberíamos hacer un throw ya que un callback puede ejecutarse en otro momento (asíncrono) y disparar una excepción dentro de un callback en otro <em>tiempo</em> puede traer graves problemas.</p>
<p>Lo que se utiliza, y no se bien si realmente es un standard (en NodeJS), es tener un argumento más (<strong>el primero</strong>) en cada callback, el cual va a ser el error:</p>
<pre class="brush: jscript; title: ; notranslate">
dao.leerDatos(function(error, datos){
   // en error tengo la excepcion (pero no hay try/ catch)
});
</pre>
<p>Porque el argumento <em>error</em> en el primer lugar?, yo creo que viene por el lado del <em>opcional</em>, en JavaScript ningún argumento es obligatorio, podemos definirlos o no, y usarlos o no, no estamos obligados a seguir una <em>firma</em> de métodos/ funciones como en otros lenguajes. Entonces de esta manera si queremos agarrar el argumento <em>datos</em> estamos obligados a agregar el argumento <em>error</em>, por su orden <img src='http://fernetjs.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Es por eso que en el caso de un callback que no devuelve nada, simplemente se dispara cuando algo termina, lo ideal sería que igualmente tenga un argumento error:</p>
<pre class="brush: jscript; title: ; notranslate">
dao.guardar(entidad, function(error){
  // etc ..
});
</pre>
<p>Bueno, y como manejo si hubo error o no?, ya que no hay try/ catch?</p>
<pre class="brush: jscript; highlight: [2,4]; title: ; notranslate">
dao.leerDatos(function(error, datos){
  if (error) {
    // manejo el error.
    return;
  }
  
  console.dir(datos);
});
</pre>
<p>Simple!, compruebo si <em>error</em> es un <a href="http://fernetjs.com/2012/04/valores-falsos-y-verdaderos/" title="Valores falsos y verdaderos: || y &#038;&#038;">valor verdadero</a> y recuerden hacer un return, o salir de ese callback de alguna otra forma, ya que sino la función continuará su ejecución, y no me suena a que queremos que suceda.</p>
<p>Mirando esto mismo de quien llama a ese manejo podemos ver como funciona:</p>
<pre class="brush: jscript; highlight: [5,10]; title: ; notranslate">
function hacerLlamada(termino) {
  
  dao.leerDatos(function(error, datos){
    if (error) {
      termino(error);
      return;
    }
    
    // algún calculo mágico
    termino(null, datos);
  });
}

hacerLlamada(function(err, datos){
  if (err) throw err;
  else console.dir(datos);
});

</pre>
<p>El ejemplo no es lo más feliz, pero lo que te quiero mostrar es como sería el que llama a esa función con otro callback. De está manera nos queda el código mucho mas ordenado y con los errores bien manejados, como si hubiera un try y catch (que va subiendo en su ejecución a medida que es disparado y atrapado por el que lo llamó), hacemos lo mismo con callbacks y somos todos felices <img src='http://fernetjs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . </p>
<h4>Links útiles y fuentes de info <img src='http://fernetjs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </h4>
<ul>
<li><a href="http://www.devthought.com/2011/12/22/a-string-is-not-an-error/">String is not an Error</a> por Guille Rauch</li>
<li><a href="http://www.w3schools.com/js/js_errors.asp">JavaScript Errors &#8211; Throw and Try to Catch</a> W3School</li>
<li><a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error">Error en MDN (MOZILLA DEVELOPER NETWORK)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2012/12/manejando-errores/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Trabajar con arreglos en javascript (parte 2)</title>
		<link>http://fernetjs.com/2012/12/trabajar-con-arreglos-en-javascript-parte-2/</link>
		<comments>http://fernetjs.com/2012/12/trabajar-con-arreglos-en-javascript-parte-2/#comments</comments>
		<pubDate>Tue, 04 Dec 2012 16:54:25 +0000</pubDate>
		<dc:creator>Fernando Rodriguez</dc:creator>
				<category><![CDATA[Lenguaje]]></category>
		<category><![CDATA[array]]></category>

		<guid isPermaLink="false">http://fernetjs.com/?p=3264</guid>
		<description><![CDATA[Como prometí anteriormente en Trabajar con arreglos en javascript (parte 1), voy a presentar en esta oportunidad 3 útiles e ... <br /><a class="more-link" href="http://fernetjs.com/2012/12/trabajar-con-arreglos-en-javascript-parte-2/">keep reading</a>]]></description>
				<content:encoded><![CDATA[<p>Como prometí anteriormente en <a href="http://fernetjs.com/2012/10/trabajar-con-arreglos-en-javascript-parte-1/" title="Trabajar con arreglos en javascript (parte 1)" target="_blank">Trabajar con arreglos en javascript (parte 1)</a>, voy a presentar en esta oportunidad 3 útiles e interesantes métodos que posee la clase array: <strong>some</strong>, <strong>every</strong> y <strong>reduce</strong>.</p>
<p>Estos ejemplos que muestro a continuación (solo simplificados para que no sea tan tedioso explicarlos y entenderlos) son piezas de código genuinas que sirven para comprender la utilización de los métodos mencionados en un contexto real.</p>
<p>Se define la clase Usuario que posee la complejidad mínima y necesaria para exhibir los ejemplos.</p>
<p>Usuario es una clase trivial con 3 propiedades: <strong>id</strong>, <strong>nombre</strong> y <strong>esAdmin</strong> y el método <strong>validar</strong> que devuelve 2 errores.<br />
Se construye el arreglo <strong>usuarios</strong> con 3 objetos de esa clase.</p>
<pre class="brush: jscript; title: ; notranslate">
function Usuario(nombre, esAdmin, id){	
	this.nombre = nombre;
	this.esAdmin = esAdmin;
	this.id = id;
		
	this.validar = function (){
		return [&quot;error1 &quot; + nombre, &quot;error2 &quot; + nombre];
	};
};

var usu1 = new Usuario('Juana', false);
var usu2 = new Usuario('Pedro', false);
var usu3 = new Usuario('Alberta', true);

var usuarios = [usu1, usu2, usu3];
</pre>
<p></br></p>
<h2 style="text-align: center">some</h2>
<p>Dada una función, <strong>some</strong> devuelve verdadero si algún elemento del arreglo cumple con la misma.<br />
El objetivo de este ejemplo es escribir el código necesario para saber si alguno de los usuarios es administrador.</p>
<h4>Usando for:</h4>
<pre class="brush: jscript; title: ; notranslate">
var hayAlMenosUnAdministrador = false;
for (var i; i &lt; usuarios.length; i++) {
	var usuario = usuarios[i];
	if (usuario.esAdmin) 
		hayAlMenosUnAdministrador = true;        
}
</pre>
<h4>Usando some:</h4>
<pre class="brush: jscript; title: ; notranslate">
var hayAlMenosUnAdministrador = usuarios.some(function(usuario){
	return usuario.esAdmin;
})
</pre>
<h4>Usando some pero más prolijo:</h4>
<pre class="brush: jscript; title: ; notranslate">
var esAdmin = function(usuario){
	return usuario.esAdmin;
};

var hayAlMenosUnAdministrador = usuarios.some(esAdmin);
</pre>
<p></br></p>
<h2 style="text-align: center">every</h2>
<p>Dada una función, <strong>every</strong> devuelve verdadero si todos los elementos del arreglo cumplen con la misma.<br />
El objetivo de este ejemplo es practicamente la misma idea anterior, solo que en este caso el objetivo es saber si todos los usuarios son administradores.</p>
<pre class="brush: jscript; title: ; notranslate">
var sonTodosAdmin = usuarios.every(esAdmin);
</pre>
<p></br></p>
<h2 style="text-align: center">reduce</h2>
<p><strong>reduce</strong> aplica una función que toma como parámetros el valor acumulado y el elemento actual del arreglo. Esa función devuelve el nuevo valor acumulado. El segundo parámetro de <strong>reduce</strong> recibe el valor inicial acumulado.<br />
El objetivo de este ejemplo es escribir el código necesario para construir un arreglo con todos los errores de validación de todos los usuarios. Recordemos que cada objeto usuario posee el método <strong>validar</strong> que devuelve los errores de validación del mismo.</p>
<h4>Usando for:</h4>
<pre class="brush: jscript; title: ; notranslate">
var todosLosErrores = [];
for (var i = 0; i &lt; usuarios.length; i++){
	var usuario = usuarios[i];
	var errores = usuario.validar();
	
	for (var e = 0; e &amp;lt; errores.length; i++)
		todosLosErrores.push(e);
}
</pre>
<h4>Mejorado:</h4>
<pre class="brush: jscript; title: ; notranslate">
var todosLosErrores = [];
for (var i = 0; i &lt; usuarios.length; i++){
	var usuario = usuarios[i];
	var errores = usuario.validar();	
	todosLosErrores = todosLosErrores.concat(errores);
}
</pre>
<h4>Usando reduce:</h4>
<pre class="brush: jscript; title: ; notranslate">
var todosLosErrores = usuarios.reduce( function(errores, usuario){
	return errores.concat(usuario.validar());
},[]);
</pre>
<h4>Usando reduce pero más prolijo:</h4>
<pre class="brush: jscript; title: ; notranslate">
var agregarErrores = function(errores, usuario){
	return errores.concat(usuario.validar());
}
var todosLosErrores = usuarios.reduce(agregarErrores,[]);
</pre>
<p>En la tercera parte de este artículo se muestran ejemplos de los métodos: <strong>forEach</strong>, <strong>filter</strong> y <strong>map</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fernetjs.com/2012/12/trabajar-con-arreglos-en-javascript-parte-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.875 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-19 12:06:55 -->
