Funciones Constructoras en JavaScript

24. enero 2012 18:14 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comentarios (0)

En un artículo anterior vimos una pequeña introducción de los objetos en JavaScript en el que se mostraron algunas características esenciales de los objetos en sí mismos. Continuamos ahora hablando de objetos y profundizando un poco en algunos conceptos.

Como ya sabemos, en la programación orientada a objetos (POO) es habitual tratar con los conceptos de encapsulación, herencia y polimorfismo. Puede que haya autores, y por qué no, también lectores, que tengan sus reservas a la hora de considerar JavaScript como un lenguaje totalmente orientado a objetos. La intención de este artículo no es entrar en este tipo de polémicas, pero lo que si podemos considerar es que JavaScript, como hemos visto anteriormente, soporta objetos y hace una simulación muy personal de otros conceptos como clases o herencia

JavaScript no tiene una notación formal de clase y recurre a las funciones constructoras para este fin. Mencionar también que JavaScript utiliza los prototipos de los objetos para propagar la herencia, algo que sin duda cuesta entender al principio y al que dedicaremos un artículo independiente más adelante.


Función constructora

Una función constructora es una función normal y corriente de JavaScript que se utiliza para definir una especie de plantilla para nuestros objetos personalizados. Veamos un ejemplo.

        function Cliente(nombre, fecha, direccion) {

            
this._nombre nombre;
            this
._fechaNacimiento fecha;
            this
._direccion direccion;
        
}

Como podemos observar, se trata de una típica función de JavaScript que admite una serie de parámetros de entrada aunque estos no son obligatorios en absoluto. La única particularidad de esta función es que se utiliza la palabra reservada this de JavaScript para definir una serie de propiedades (también podrán ser métodos) que formarán parte de nuestros objetos personalizados.

En la siguiente ilustración vemos cómo podemos utilizar esta función constructora para crear instancias de nuestros objetos personalizados

El operador new utilizado junto a una función de JavaScript es lo que nos permite obtener un objeto constructor o función constructora. Lo que sucede por debajo es que new primeramente crea un objeto sin propiedades y posteriormente llama a la función pasándole el nuevo objeto como valor de la palabra reservada this. Finalmente, la función nos devuelve un nuevo objeto con las propiedades y métodos definidos dentro de la constructora. Como se aprecia en el intellisense de la imagen observamos que el nuevo objeto miCliente tiene todas las propiedades definidas anteriormente dentro del constructor.

Como hemos comentado no es necesario que el constructor tome parámetros, podemos crear una plantilla en blanco e ir rellenando los objetos con datos cuando lo necesitemos.

        //Constructor vacio
        
function Cliente() {

            
this._nombre "";
            this
._fechaNacimiento = null;
            this
._direccion "";
        
}

        
//Creamos el objeto y le asignamos valores
        
var cliente = new Cliente();
        
cliente._nombre "Cristina Rodriguez";
        
cliente._fechaNacimiento = new Date(1987325);
        
cliente._direccion "Plaza Bilbao 25";

Cuando hablamos de los objetos en JavaScript vimos que se podían definir objetos por medio de la notación JSON. Pues bien, también podemos definir objetos por medio de una función que devuelva un literal de objeto. En este caso, la función constructora hace de envoltorio para el código JSON de definición del objeto permitiéndonos reutilizar el código para crear distintas instancias del mismo.

        function Cliente(nombre, fecha, direccion) {

            
return {
                _nombre: nombre,
                _fechaNacimiento: fecha,
                _direccion: direccion
            }
;
        
}

Debemos tener en cuenta que siempre que utilicemos un return dentro de una función constructora, el objeto devuelto, ocultará al resto de miembros que intentamos definir. No importa si la función devuelve un objeto literal, una cadena, un número, etc. Esto siempre ocultará a los demás miembros públicos que hayamos definido.

        function Cliente(nombre, fecha, direccion, email) {

            
this._email email;

            return 
{
                _nombre: nombre,
                _fechaNacimiento: fecha,
                _direccion: direccion
            }
;
        
}

En este ejemplo cabría esperar que un objeto creado a partir de esta función constructora tuviera 4 propiedades públicas. Pero no es así, la propiedad email queda ocultada por el objeto que se devuelve con return, por lo que obtendríamos un objeto idéntico al del ejemplo anterior.

 

Miembros de instancia

Las propiedades y métodos definidos dentro de la función constructora se pueden denominar miembros de instancia dado que cada objeto creado a partir de la función constructora guardará su propia copia de los miembros definidos. Veamos ahora como podemos diferenciar entre miembros de instancia públicos y privados.

Hace unos instantes hemos definido una serie de propiedades públicas en nuestros objetos por medio de variables JavaScript y la palabra reservada this. Para definir métodos públicos procederemos de la misma forma con la salvedad de que utilizaremos una función de JavaScript. También podemos definir propiedades y métodos privados al objeto simplemente definiendo variables y funciones JavaScript dentro de la función constructora utilizando el var de toda la vida. Es decir, para definir miembros públicos utilizaremos this y para los miembros privados utilizaremos var.

Veamos un ejemplo de código simplificado para clarificar todo esto. 

        function Cliente(nombre, fecha, direccion) {

            
//Propiedades privadas
            
var edad;

            
//Métodos privados
            
var calcularEdad = function () {
                
var actual = new Date().getYear();
                var 
nacimiento fecha.getYear();

                if 
(actual <nacimiento)
                    edad 
"Error: no se ha podido calcular";
                else
                    
edad actual - nacimiento;
            
}

            
//Propiedades públicas
            
this._nombre nombre;
            this
._fechaNacimiento fecha;
            this
._edad edad;
            this
._direccion direccion;

            
//Métodos públicos
            
this._presentarse = function () {
                calcularEdad()
;

                document
.write(
                    
"Hola, mi nombre es " this._nombre + " y tengo " this._edad + " años."
                    
);
            
}
        }

Existen autores, como Douglas Crockford, que hacen una pequeña distinción entre métodos públicos y métodos privilegiados. Esta distinción se basa en el hecho de que existe otra forma de definir métodos públicos en los objetos por medio del prototipo de la función constructora. Ya hemos comentado que hablaremos de los prototipos en otro artículo cuando hablemos también de la herencia.

Pero para los impacientes les adelanto que con métodos privilegiados se refiere precisamente a los métodos definidos dentro del cuerpo de la función con la palabra reservada this, dado que estos métodos tienen el privilegio de tener acceso a las variables y métodos privados. Mientras que los métodos definidos por medio del prototipo de la función constructora no tendrán nunca este acceso o privilegio y son denominados simplemente métodos públicos. Podéis leer sobre esta original idea en este artículo escrito por el propio Crockford.

Creo que es importante mencionar también que desde un método privado no tendremos acceso directo a miembros públicos. Esto es así porque como hemos comentado anteriormente this hace referencia al objeto devuelto por la función constructora y para la función privada este objeto se encuentra fuera de ámbito. De hecho, existe una solución a este aparente inconveniente que pasa por utilizar una potente característica de JavaScript, los closures, que estudiaremos a fondo en otra ocasión. Veamos ahora que sucede si intentamos el acceso directo.

        function Constructor(msjPrivado, msjPublico) {

            
var propiedadPrivada msjPrivado;
            this
.propiedadPublica msjPublico;

            var 
metodoPrivado = function () {
                
alert(propiedadPrivada);
                alert
(this.propiedadPublica);
            
};

            this
.metodoPublico = function () {
                metodoPrivado()
;
            
};
        
}

        
var obj = new Constructor("mensaje privado""mensaje público");
        
obj.metodoPublico();

Cuando ejecutemos este código recibiremos dos alertas, aunque una de ellas, la que intenta mostrar el valor de la propiedad pública nos notificará un undefined. Es aún peor si intentamos acceder a la propiedad pública sin la sentencia this, directamente tendremos un error del tipo variable no definida. 

 

Miembros estáticos

Los miembros estáticos o también llamados miembros de clase son aquellos estados o comportamientos comunes a todas las instancias de la clase. En estos casos puede tener mucho más sentido no definirlos dentro de la función constructora, dado que todas las instancias de los objetos creadas a partir de ella contendrán una copia de estos miembros que son comunes a todos los objetos creados. Supongamos que en nuestro ejemplo Cliente queremos tener una propiedad que almacene el IVA que se les va aplicar a todos nuestros clientes sin excepción. 

        function Cliente() {
            
            
//Definimos los miembros de instancia...   
        
}


        
//Definimos una propiedad estática
        
Cliente.IVA 18;

        
//En otro punto del código hacemos uso del IVA
        
var total neto + (neto * (Cliente.IVA / 100));

Igualmente, si tenemos un método que devuelva siempre el mismo objeto o valor, deberíamos definirlo a nivel de la función constructora. Este podría ser el caso de un método que devuelva una instancia de inicialización con valores por defecto para nuestro objeto Cliente.

Si es la primera vez que el lector se asoma a la programación de objetos con JavaScript puede resultarle extraño este proceder pero muchos objetos nativos de JavaScript siguen este criterio. Por ejemplo, el objeto Number utiliza una propiedad estática que devuelve el mayor número posible en JavaScript, Number.MAX_VALUE. Y el objeto Date utiliza un método estático para analizar una fecha en formato cadena y devolver su representación en milisegundos desde una fecha siempre constante en JavaScript, Date.parse(string)

 

Comprobar la función constructora de un objeto

Todos los objetos de JavaScript, ya sean nativos o de usuario, tienen una propiedad constructor que heredan del objeto genérico Object, la cual hace referencia a la función constructora que inicializa el objeto lo que en principio (ahora veremos por qué digo esto) nos permite determinar la función constructora de un objeto, y casi por extensión, la clase de éste.

        function Cliente() {
            
            
//Definición de miembros de Cliente...
        
}

        
var unCliente = new Cliente();

        if 
(unCliente.constructor == Cliente) {
            
            
//Hacer algo con el objeto unCliente
        
}

Por otro lado también podríamos utilizar el operador instanceof para determinar la constructora de un objeto pero con algunas diferencias. El operador instanceof, a diferencia del anterior, comprueba la jerarquía del objeto, por lo tanto podríamos preguntar directamente sobre el objeto padre con idénticos resultados.

        unCliente instanceof Cliente // Devuelve true
        
unCliente instanceof Object // Devuelve true

Lamentablemente en JavaScript nada es tan sencillo como parece. Las cosas se complican cuando hablamos de modificar el prototipo de un objeto y la propiedad constructor parece perder la referencia a la función constructora. Pero todo esto es harina de otro costal y se sale por completo de la intención de este artículo. Recomiendo al lector que lea Constructors considered mildly confusing para comprender bien el comportamiento de la propiedad constructor y del operador instanceof.

Y para complicar más las cosas, también tenemos a nuestra disposición el operador unitario typeof. De nuevo, recomiendo a los lectores interesados en profundizar en estos temas los artículos The Secret Life of JavaScript PrimitivesFixing the JavaScript typeof operator.

Implementar un sitio web privado con ASP.NET MVC

24. diciembre 2011 20:44 by Oscar.SS in Desarrollo Web  //  Tags: ,   //   Comentarios (0)

Bueno, para terminar el año operativo de este blog que mejor que un artículo de los facilitos. No es cuestión ya en estas fechas de complicarse la vida. Jejeje...que disculpas me pongo ;-)

Vamos a implementar con ASP.NET MVC la funcionalidad mínima para que un sitio web sea privado a todos los usuario no registrados. Utilizaremos la autentificación de usuarios por formulario y veremos como podemos aprovechar parte del código de la plantilla de aplicación que viene por defecto cuando creamos un nuevo proyecto ASP.NET MVC. Por otra parte crearemos un filtro personalizado que será el encargado de gestionar que usuarios tienen acceso para ejecutar un controlador o método de acción, o lo que es lo mismo, que usuarios tienen permiso para visualizar una vista concreta.

 

Paso 1. Creamos un nuevo proyecto ASP.NET MVC de tipo Internet Application

Seguramente el lector ya iniciado conocerá de sobra que esta plantilla de ASP.NET MVC contiene una funcionalidad mínima de un sitio web con un par de páginas y autenticación de usuarios por formulario que es precisamente la parte que nosotros vamos a reutilizar para el caso que nos ocupa. La validación de las credenciales de los usuarios que viene por defecto en esta plantilla utiliza el sistema de membresía de ASP.NET, el cual, nosotros vamos a sustituir más adelante.

 

Paso 2. Cambiar la ruta por defecto en el Global.asax

Parece lógico pensar que si todo el sitio web va a ser privado deberíamos iniciar la aplicación directamente en el formulario de login para que los usuarios escriban sus credenciales. Seguramente el lector ya sabrá que en el Global.asax existe un método RegisterRoutes() que es invocado al iniciar la aplicación para crear la tablas de rutas que utilizará el sistema de routing. En ese método podemos especificar que la ruta por defecto para nuestra aplicación será el formulario de login.

            routes.MapRoute(
                
"Default"// Route name
                
"{controller}/{action}/{id}"// URL with parameters
                
new { controller "Account", action "LogOn", id UrlParameter.Optional } // Parameter defaults
            
);

 

Paso 3. Validación de usuarios personalizada

Aquí es donde vamos a sustituir el sistema de membresía de ASP.NET por un método de validación de usuarios personalizado. Vayamos al controlador AccountController y modifiquemos de la siguiente forma el método de acción LogOn que maneja las peticiones por HTTP POST.

        public ActionResult LogOn(LogOnModel model)
        {
            
if (ModelState.IsValid)
            {
                
if (UserServices.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe)
;

                    return 
RedirectToAction("Index""Home");
                
}

                ModelState.AddModelError(
"""The user name or password provided is incorrect.");
            
}

            
// If we got this far, something failed, redisplay form
            
return View(model);
        
}

Si comparamos este código con el que viene por defecto veremos que tan solo se han modificado dos cosas. En primer lugar se ha eliminado el parámetro returnUrl (así como la comprobación de su formato) del método de acción. Cuando la autentificación de usuarios se gestiona directamente desde el Web.config, como hemos hecho siempre en ASP.NET, este parámetro contiene la ruta a la que intentaba navegar el usuario no autentificado. Dado que nosotros vamos efectuar este proceso por medio de un filtro global, no haremos uso de este parámetro.

En segundo lugar, hemos sustituido la validación de las credenciales del usuario por medio de la clase Membership por un sistema propio de validación. Vamos, esto no es más que un método que llame a nuestra base de datos, en este caso UserServices.ValidateUser(), y compruebe si existe un usuario con estas credenciales, y ya de paso que compruebe que este sea único...¡por si las moscas! :-)

 

Paso 4. Limpiamos el web.config

Por defecto el web.config viene configurado para hacer uso del sistema de membresía que hemos dicho que no vamos a utilizar, así que eliminamos del web.config las siguiente secciones.

  <!--Sustituimos la cadena de conexión que viene por defecto por la que corresponda-->
  
<connectionStrings>
    
<add name="ApplicationServices"
         connectionString
="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
         providerName
="System.Data.SqlClient" />
  </
connectionStrings>

  
<!--Administración y autenticación de cuentas de usuario-->
  
<membership>
    
<providers>
      
<clear/>
      
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
           enablePasswordRetrieval
="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
           maxInvalidPasswordAttempts
="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
           applicationName
="/" />
    </
providers>
  
</membership>

  
<!--Configuración de los valores de los perfiles de usuario-->
  
<profile>
    
<providers>
      
<clear/>
      
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
    </
providers>
  
</profile>


Paso 5. Codificamos un filtro

El propio framework de ASP.NET MVC nos ofrece una serie de filtros  permitiéndonos la ejecución de código de forma limpia a modo de atributos declarativos. Como en otras ocasiones ASP.NET MVC nos permite extender el framework escribiendo un filtro personalizado que utilizaremos para permitir el acceso o no de los usuarios a los distintos recursos de la aplicación.

    public class RequiredAuthenticationAttribute : FilterAttribute, IAuthorizationFilter
    {
        
/// <summary>
        /// Determina si va a realizar la comprobación de autenticación para un método de acción o 
        /// controlador. Por defecto es true.
        /// </summary>
        
public bool Check { get; set; }

        
public string Controller { get; set; }
        
public string Action { get; set; }

        
public RequiredAuthenticationAttribute()
        {
            Check 
= true;
        
}

        
public void OnAuthorization(AuthorizationContext filterContext)
        {
            
//Si es false no se realiza la comprobación de autenticación
            
if (!Check) return;

            
var routeValueDictionary = new RouteValueDictionary(
                
new
                    
{
                        
//El operador doble interrogación se invierte por validaciones de script en este blog
                        
action Action ¿¿ "LogOn",
                        controller 
Controller ¿¿ "Account"
                    
});

            if 
(!filterContext.HttpContext.Request.IsAuthenticated)
                filterContext.Result 
= new RedirectToRouteResult(routeValueDictionary);
        
}
    }

 

Paso 6. Registramos el filtro globalmente

Como nuestra intención es que todo el sito web sea privado para todos aquellos usuarios no registrados, en el Global.asax añadimos el filtro a la colección de filtros globales de ASP.NET MVC, de esta forma antes de ejecutar cualquier controlador se ejecutará el código de nuestro filtro personalizado. Y si el usuario que ejecuta el controlador no esta autenticado le devolverá siempre a la vista de login.

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(
new HandleErrorAttribute());
            
filters.Add(new RequiredAuthenticationAttribute());
        
}

 

Paso 7. Definir métodos públicos a todos los usuarios

En el paso anterior hemos establecido que se ejecute el código de nuestro filtro antes de ejecutar cualquier controlador o método de acción. Pero tenemos que permitir el acceso al formulario de login a todos los usuarios para que puedan escribir sus credenciales. Para ello firmamos los dos métodos de acción (GET y POST) que gestionan el formulario de autenticación de usuarios.

        [RequiredAuthentication(Check = false)]
        
public ActionResult LogOn()
        {
            
return View();
        
}

        [HttpPost]
        [RequiredAuthentication(Check 
= false)]
        
public ActionResult LogOn(LogOnModel model)
        {
            
//Aquí va el código que hemos modificado en el paso 3
        
}

Como se puede observar, utilizamos el filtro y establecemos a false la propiedad Check para que todos los usuarios tengan permiso para visualizar y enviar el formulario de login. También podríamos especificar por medio de las propiedades Controller y Action del atributo un formulario de login distinto al de por defecto para redirigir a los usuarios que no tengan credenciales. 

 

Paso 8. Proteger carpetas y archivos

Con lo visto hasta ahora ya tendríamos la funcionalidad mínima para comprobar la autenticación de los usuarios. Pero supongamos que nuestra aplicación contiene documentos PDF, imágenes o cualquier tipo de archivo sensible de ser protegido. Dado que nuestro filtro sólo protege el contenido entregado por el propio método de acción, debemos especificar en el Web.config que carpetas o archivos deben ser protegidos. 

Por ejemplo, en el caso de una carpeta que contiene las fotos de los usuarios, si queremos que estas no sean accesibles directamente por URL a todos los usuarios debemos configurar la aplicación para protegerlas.

  <location path="UserPhotos">
    
<system.web>
      
<authorization>
        
<deny users="?"/>
      </
authorization>
    
</system.web>
  
</location>

 En combinación con los elementos location y deny, especificamos que el directorio que contiene las fotos de los usuarios sólo será accesible para los usuarios que ya se han registrado e identificado. Esta forma de proteger directorios no es exclusiva de MVC, de hecho, es la forma tradicional de hacerlo en ASP.NET.

Para finalizar mencionar que todo lo que hemos visto tan solo es un sencillo ejemplo para intentar mostrar algunos conceptos como los filtros, extensión del framework o la gestión de usuarios por formulario. De todas formas puede ser válido para pequeñas aplicaciones con pocos usuarios, pero para aplicaciones de más envergadura habría que realizar algo más de trabajo como por ejemplo con la gestión de roles.

Bueno, espero que a pesar de su sencillez le pueda servir a alguien para acercarse un poco más ASP.NET MVC y a todo lo que contiene.

¡¡Felices fiestas y hasta el año que viene!! :-)

Crónica del Life Is Soft 2011

12. noviembre 2011 00:26 by Oscar.SS in Información, Personal  //  Tags: ,   //   Comentarios (9)

Ayer tuve la suerte de poder asistir al "Life Is Soft 2011" que este año se ha celebrado en la ciudad Asturiana de Gijón. Creo recordar que hacía más de 25 años que no visitaba esta ciudad y la verdad la he encontrado muy bonita y limpia. Ni siquiera el día nublado y tímidamente lluvioso han estropeado los bellísimos paisajes naturales o la espectacular arquitectura de sus edificios emblemáticos.

Patio de la Universidad Laboral En cuanto al evento en sí, se ha celebrado en el Teatro Principal de la Universidad Laboral. Nunca había visitado el centro universitario de Gijón y sinceramente tengo que decir que me ha causado una agradable impresión. Es un edificio espectacular, bien cuidado y acondicionado.

La temática del Life Is Soft no es esencialmente técnica. Está más dirigida a todo lo que ocurre alrededor, e incluso después, del proceso de codificación. Como vender el software, el equipo humano, diseño y todo aquello que muchas veces los técnicos (me incluyo por supuesto) no damos la debida importancia. Pero la tiene, sobre todo si realmente pretendes hacer de tu código un negocio. Por lo menos a mí, me ha parecido interesante empaparme de estos conceptos más globales y externos al código que evidentemente mueven nuestra industria.

La dinámica de Life Is Soft ha sido una sorpresa agradable en cuanto a su ejecución. Los ponentes se sucedían unos detrás de otros con solo 12 o 15 minutos para comunicar sus experiencias y "penas". Y como director de la línea del tiempo, haciendo las veces de maestro de ceremonias, se encontraba Mario Conde. Este tipo de ejecución, al estilo de los monólogos televisivos, ciertamente son muy ágiles, entretenidas y creo yo más comunicativas si cabe. Mejor quedarte con una sola idea en 15 minutos que un par de bostezos en 1 hora.

A continuación os resumo muy brevemente algunas de las presentaciones por si es de vuestro interés.

¿Cómo ser rentable en una empresa de software?

Santiago Cabaleiro apunta que el éxito del software está en focalizar. Focalizar en el cliente (o el usuario), saber realmente cual es su necesidad o que es lo que más valora. Por otra parte focalizar en lo que mejor hace tu empresa y de estas habilidades focalizar en las que hacemos mejor que la competencia. Hay que pensar a largo plazo y para mantener el foco durante un largo periodo es necesaria implicación, indicadores (métricas) e ingresos periódicos.

 

Playa de San Lorenzo Las personas trabajando a gusto damos lo mejor

La presentación de Lola Calvo tengo que reconocer que ha sido una bocanada de aire fresco. No recuerdo ningún evento de software, ni de ningún otro tipo, ya sea técnico o empresarial, en los que se hiciera una sola mención al equipo humano que evidentemente se encuentra detrás de todo lo que hacemos. Desde luego para una empresa conseguir y retener un buen equipo humano con talento es vital, pero para nosotros, sentir que la empresa tiene en cuenta a las personas y no solo a los números, es decisivo.

Aunque parezca mentira, apuntaba que las empresas debería tener en cuenta conceptos como respeto, confianza, que ofrece la empresa (captación), economía, familia (tiempo libre), salud, las necesidades de las personas cambian con el tiempo (desarrollo), esfuerzo por retener el talento, etc.

¿A que parece una utopía?, y seguramente lo sea. Si encuentro una empresa de software que realmente tiene en cuenta solo la mitad de estos factores...¡me caso con ellos!

 

Evolucionamos en tecnología para innovar en software

Hablando de los rápidos y continuos cambios tecnológicos que sufrimos los que trabajamos con software, David Gutiérrez aconseja intentar ser el más adaptado, no el más grande. Siempre que sacamos una nueva versión de producto aumentamos la funcionalidad, comenta que es preciso también quitar funcionalidad para una mejor adaptación.

 

Diseño

Y como no podía ser de otra forma el diseño también estuvo presente. Bueno, no hay mucho que comentar sobre esto, es evidente que si el destino final de tu software va a ser usado por personas, debe tener un aspecto bonito y también usable. Nicolás Osuna comentó un dato que me pareció curioso: según Apple y Google si un campo no es utilizado por al menos el 80% de los usuarios hay que eliminarlo.

 

Ponencia de José Manuel AlarcónLa venta de software

Finalmente el destino de todo software es la venta, ya sea económicamente o a cambio de otros intereses o servicios. Cecilio Labrada habló sobre un modelo clásico de ventas, AIDA, que naturalmente yo no conocía pero me pareció curioso.

 

¡No hagas eso! Los dos errores más graves en las PYME tecnológicas a la hora de vender

Un regalo muy valioso los dos consejos de José Manuel Alarcón sacados directamente de su experiencia profesional como empresario.

Falta de diferenciación. Las PYME deben de competir en el ámbito de la especialización olvidándose de conceptos como solución integral. Es un error, sobre todo cuando se empieza, intentar abarcarlo todo. ¡Especialízate y concreta!

Competir en precio. Cuando una PYME se intenta posicionar con precios bajos condiciona muchos sus márgenes y obtiene un mal posicionamiento por marketing. Además tus competidores directos siempre pueden hacer lo mismo y en cuanto a las empresas grandes tienen mayor pulmón financiero para resistir la guerra de precios.

 

Marketing online: Redes sociales

Sobre las redes sociales y las empresas, personalmente lo extendería también a las personas, Fernando Maltrana nos habló de su importancia pero también de su conveniencia en según qué casos.

Resumiendo mucho redacto los puntos claves que se comentaron. Estrategia (hay que tener un objetivo), audiencia (contar y escuchar), autenticidad, privacidad (¿le interesa a todos lo que publico?), constancia y equilibrio (no abrumar), coherencia y tráfico medible.

 

Con estas vistas me desperté yo!! Fear Uncertainty and Doubt

Marcos Eguillor nos presentó un concepto de estrategia comercial que me sorprendió bastante. No porque no me lo esperaba, más bien porque sea una estrategia reconocida, estudiada y medible. Por lo que yo entendí, que tampoco soy ningún experto, es una estrategia comercial que utilizan grandes empresas cuando su negocio está perdiendo. Estas empresas implantan esta estrategia para sembrar el FUD.

 

¡¡Despierta!!

Bueno, bueno...como colofón final (disculpen el pleonasmo) Alfonso Gutiérrez hizo un llamamiento, quizás poco ortodoxo pero muy valiente debo añadir, a la motivación en esta época de crisis. A salir de esta prisión que es el miedo y sus barreras mentales. A luchar contra toda la información negativa actual que nos acecha. A no ser víctimas del pesimismo colectivo.   Una frase: Sé tú mismo, todos los demás ya están cogidos, Oscar Wilde. Un mensaje: ¡¡Despierta y sigue soñando!!

 

Resumiendo

Un evento dinámico, entretenido, ágil, con energía transmisora, que no deja indiferente y del que me llevo cosas aprendidas y otras a considerar. Pero como no podía ser de otra forma también hubo un par de charlas un poco peñazo. Fijaros que curioso, creo que fueron precisamente las presentaciones que se excedieron de los 12 o 15 minutos.

Objetos en JavaScript

9. noviembre 2011 19:51 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comentarios (0)

Los desarrolladores que venimos de lenguajes OO podemos encontrarnos con algunos detalles desconcertantes a la hora de trabajar con objetos JavaScript, dado que estos objetos difieren bastante de los conceptos que estamos acostumbrados a tratar. En primer lugar vamos a dar una definición más o menos formal y después veremos algunos ejemplos que explicarán mejor esta definición.

"Los objetos de JavaScript son colecciones de propiedades cada una con un nombre y un valor. Este valor puede ser otro objeto, por lo tanto, podemos decir también que los objetos JavaScript son contenedores para otros objetos JavaScript".

 

Crear objetos

En JavaScript no disponemos del concepto de clases, como tal, que nos permitan crear un contenedor o firma para nuestros objetos. En JavaScript los objetos se crean dinámicamente bajo demanda. Veamos unos ejemplos.

//Creamos un objeto Cliente
var cliente = new Object();

//Le creamos dínamicamente sus propiedades y le asignamos valores
cliente.nombre "Pedro García";
cliente.direccion "Calle San Juan, 3, 5º B";
cliente.fechaNacimiento = new Date(1975323);
cliente.empleoActual "Soldador";

Como podemos observar, en primer lugar creamos una instancia de Object y a continuación creamos sus propiedades asignándoles un valor. El añadir propiedades a un objeto se puede hacer en cualquier punto de nuestro código siempre que lo necesitemos. Es decir, un objeto JavaScript no tiene un conjunto de propiedades y método predefinidos como si lo tienen gracias a las clases los lenguajes OO. Esta elasticidad es muy potente dándonos plena libertad sobre las características de nuestros objetos.

Mencionar también que no disponemos de un compilador que nos avise de errores por lo que es muy importante escribir bien el nombre de las propiedades. Por ejemplo, supongamos que en algún punto de nuestro código necesitamos cambiar el domicilio de nuestro cliente.

cliente.dirección "Plaza Castilla, 4, 12º Izq";

Fijaros bien en que el nombre de la propiedad ahora tiene un acento. Lo que hemos conseguido con este error es que se creen dos propiedades con valores diferentes en nuestro objeto Cliente, una propiedad "direccion" y otra propiedad "dirección". Esto nos puede volver locos cuando tratemos de recoger el valor de la propiedad y descubramos que no se ha cambiado y en su lugar se han creado dos propiedades parecidas...¡mucho cuidado!

 

Objetos como contenedores de otros objetos

Cuando dimos la definición de un objeto JavaScript dijimos que se comportaban como contenedores de otros objetos. ¿En el ejemplo anterior de nuestro Cliente esto no ha sido así?. Desde luego que si, realmente hemos creado un objeto Cliente que contiene 3 instancias de String y una instancia de Date. Quizás lo veamos más claro con un ejemplo de código.

//Creamos un objeto para almacenar los valores de la dirección de nuestro cliente
var direcClient = new Object();
direcClient.calle "Castillo de Candanchú";
direcClient.numero "23";
direcClient.piso "5º B";

//Creamos un nuevo cliente y le asignamos el objeto direcClient a la propiedad direccion
var cliente = new Object();
cliente.nombre "Sergio Rodriguez";
cliente.direccion direcClient;
cliente.fechaNacimiento = new Date(1975323);
cliente.empleoActual "Progamador de los buenos";

//Accedemos a los valores de la dirección
var suCalle cliente.direccion.calle;

De hecho, si realmente los objetos son colecciones, ¿que nos impide recorrer el objeto como si de un Array se tratara?. No nos lo impide nada en absoluto. Veamos.

            for (var item in cliente) {
                
alert("Propiedad: " + item + "\nValor: " + cliente[item]);
            
}

La variable item en cada iteración mantiene una referencia al nombre de cada propiedad del objeto. O dicho de otro modo, en cada iteración la variable almacena una cadena de texto con el nombre de la propiedad. Veamos un par de resultados de ejecutar el código anterior.

Creo que ahora queda más claro eso de que los objetos son colecciones de propiedades que contienen otros objetos. Es importante comentar dos aspectos de esta característica.

En primer lugar, el nivel de anidamiento de objetos no tiene límites, podremos anidar tantos objetos como necesitemos para representar nuestro modelo. Y en segundo lugar, comentar que las funciones de JavaScript también son objetos y por lo tanto también pueden estar contenidas dentro de las propiedades de otros objetos. Pero esto lo veremos más adelante con detenimiento.

 

Expresiones como nombres de propiedades

Hasta ahora hemos visto que los nombres de las propiedades de nuestros objetos JavaScript son identificadores normales y corrientes. ¿Pero qué sucede si necesitamos identificadores más complejos?. Como por ejemplo "Empleo Actual", o "empleo.Actual", o "El empleo de este cliente", etc.

En este caso podemos utilizar una expresión como una propiedad del objeto de la siguiente forma.
 
nombreObjeto[expresión] = valor de la propiedad;
 
Esto es muy útil cuando a priori no conocemos el nombre de la propiedad, por ejemplo porque será suministrado por el usuario en un campo de texto. Veamos un ejemplo.
 
//Definimos unas cadenas que representarán nuestros nombres de propiedades
var nombrePropiedad "Empleo" "actual" "del" "cliente!!";

function 
GetNombrePropiedad() {
    
return "Nombre del cliente";
}

//Creamos la propiedades en el objeto y le asignamos valores.
var cliente = new Object();
cliente[GetNombrePropiedad()] "Raquel Gutierrez";
cliente[nombrePropiedad] "Doctora";

//Desde otro código accedemos a los valores de las propiedades
var nombreCliente cliente[GetNombrePropiedad()];
var 
empleoCliente cliente[nombrePropiedad];

 

Notación JSON para definir objetos

La sintaxis que hemos utilizado hasta ahora para definir objetos y asignar valores a las propiedades es muy familiar para los programadores de cualquiera de los lenguajes de la familia .NET y especialmente para los de C#. Pero JavaScript va mucho más allá y nos permite definir objetos con la sintaxis JSON a modo de literales de objetos.

var cliente =
    
{
        nombre: 
"Nuria Perez",
        fechaNacimiento: 
new Date(19731213),
        empleoActual: 
"Ingeniera",
        direccion: 
            {
                calle: 
"San Pascual",
                numero: 
23,
                piso: 
"3 C"
            
}
    }
;

 Esta es una forma mucho más compacta de escribir y definir código de objetos y desde luego también es más intuitiva sobre todo, si como en el ejemplo, tenemos objetos anidados.

 

El objeto window

El objeto window es el objeto más alto en la jerarquía del navegador, todos los demás objetos, ya sean nativos de JavaScript o creados por nosotros, cuelgan del objeto window, el cual será único para cada ventana o pestaña del navegador.

Cuando en JavaScript definimos una variable fuera del cuerpo de cualquier función, solemos decir que es una variable global. Pues bien, en realidad lo que estamos haciendo es crear una propiedad en el objeto window y asignarle un valor.

De hecho, a mí personalmente me gusta mucho más la notación que se aprecia en la imagen a la hora de recoger el valor de la variable o propiedad del objeto window. En funciones con muchas líneas de código, si hacemos referencia al objeto window, queda más claro que variables son de ámbito de la función y cuales son globales.

Por cierto, fijaros bien en el intellisense de la imagen anterior, en la declaración de la función sucede exactamente lo mismo. Lo que estamos haciendo en realidad al definir un método o función es asignárselo al objeto window. ¡Todo cuelga del objeto window!

 

Intellisense de JQuery en Visual Studio

2. octubre 2011 12:10 by Oscar.SS in Desarrollo Web, Herramientas  //  Tags: ,   //   Comentarios (0)

Con la llegada de JQuery a Visual Studio también llegó un archivo con la extensión vsdoc.js con toda la documentación necesaria para disfrutar de intellisense al escribir nuestro código cliente. Es algo muy sencillo, pero a veces estas cosas se pasan por alto.

 

Intellisense en páginas HTML

Si nos vemos en la obligación de escribir bloques de script en las propias páginas HTML, para disfrutar del intellisense de JQuery bastará con añadir una referencia al archivo de documentación con la extensión "vsdoc.js".

Como podemos apreciar en la imagen, al añadir la referencia al archivo mencionado, tenemos a nuestra disposición información sobre la función JQuery representada por el símbolo $.

Es importante mencionar dos aspectos. En primer lugar, cuando trabajemos en un proyecto ASP.NET MVC podemos vernos tentados de utilizar la siguiente sentencia.

<script src="@Url.Content("~/Scripts/jquery-1.5.1-vsdoc.js")" type="text/javascript"></script>

 Pero esto no funcionará dado que la referencia al archivo se realizará en tiempo de ejecución al tratarse de código de servidor.

Por otra parte es necesario mencionar que cuando despleguemos nuestra aplicación en producción debemos sustituir las referencias a los archivos de documentación por los archivos tradicionales, o incluso mejor aún, por las referencias a los archivos con la denominación "min.js".

 

Actualización 03/10/2010

Hablando esta mañana con mi compañero Omar Del Valle sobre este sencillo post, me comenta un pequeño truco que me ha parecido curioso e interesante para incluir aquí. Fijaros en la imagen siguiente.

En efecto, tenemos la referencia al archivo con la extensión "min.js" que como sabesmos es la que debería publicarse en el servidor de producción ya que al estar minimizada el tráfico de red generado es menor, tarda menos en cargar el script, etc.

Pero también tenemos una referencia, dentro de un if de servidor, al archivo de documentación "vsdoc.js". ¿Que conseguimos con esto?.

Por una parte, como se aprecia en la imagen, Visual Studio entiende la referencia al archivo de documentación y nos permite tener intellisense de JQuery. Y por otra parte, a la hora de publicar nuestra aplicación en producción, si se nos olvida eliminar en alguna página las referencias al archivo de documentación, gracias  al if(false), están nunca serán incrustadas en el HTML de vuelta al cliente.

Es necesario aclarar, que igualmente habría que eliminar esta linea de código al subir a producción, dado que el compilador tiene un pequeño trabajo extra, pero es cierto que en caso de olvido es un mal menor.

Por cierto, este truco también funciona con las páginas Web Forms y las etiquetas <%= %>.

 

Intellisense en archivos JS

Si nuestro archivo se encuentra en el mismo directorio que el archivo de documentación vsdoc.js, automáticamente tendremos a nuestra disposición las bondades del intellisense. Esto es así porque Visual Studio por defecto, ya sea una aplicación Web Form o MVC, buscará en la carpeta ~/Scripts el archivo de documentación y si lo encuentra creará por nosotros la referencia en nuestro archivo JS.

En el caso de que nuestro archivo JS se encuentre en otro directorio o anidado dentro de ~/Scripts, por ejemplo Scripts/Login/miArchivo.js, debemos crear nosotros la referencia de la siguiente forma.

/// <reference path="../jquery-1.5.1-vsdoc.js" />

Colocando esta linea de código al principio de nuestro archivo JS tendremos el intellisense disponible.

 

Intellisense en nuestras propias funciones

También podemos documentar nuestras funciones al igual que lo hacemos en nuestro código de servidor C#, VB o cualquier otro. Mirar el siguiente código.

Mencionar que las etiquetas summary, param y returns deben estar colocadas dentro del cuerpo del la función.

¡Espero que sea útil!

Someone Said

No puedes olvidar, pero puedes intentar perdonar. Y posiblemente nunca te perdones por haberlo intentado.

OSS

Recent Comments

Comment RSS

Month List