PATCH y OPTIONS: nuevos verbos HTTP para métodos de acción en ASP.NET MVC 4

21. November 2012 00:01 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (0)

En ASP.NET MVC 3 teníamos a nuestra disposición los atributos HttpGetAttribute, HttpPostAttribute, HttpPutAttribute, HttpDeleteAttribute y HttpHeadAttribute. Estos atributos, que nos permiten filtrar que verbos HTTP aceptarán nuestros métodos de acción, son tratados como una enumeración de flags dentro de la clase AcceptVerbsAttribute. Veamos por ejemplo la implementación del atributo para el verbo POST.

        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
        
public sealed class HttpPostAttribute : ActionMethodSelectorAttribute
        {
            
private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);

            public override bool 
IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
            {
                
return _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
            
}
        }

Se crea una instancia de la clase AcceptVerbsAttribute y se le pasa al constructor el valor para este verbo de la enumeración HttpVerbs. El constructor llama a su vez al método AcceptVerbsAttribute.EnumToArray() para construir la lista de verbos HTTP que soportará nuestro método de acción. A continuación podéis ver la implementación de este método y los nuevos verbos añadidos en ASP.NET MVC 4.

        private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List<string> verbList, string entryText)
        {
            
if ((verbs & match) !0)
            {
                verbList.Add(entryText)
;
            
}
        }

        
internal static string[] EnumToArray(HttpVerbs verbs)
        {
            List<
string> verbList = new List<string>();

            
// ASP.NET MVC3
            
AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET");
            
AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST");
            
AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT");
            
AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE");
            
AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD");
            
            
// New in ASP.NET MVC4
            
AddEntryToList(verbs, HttpVerbs.Patch, verbList, "PATCH");
            
AddEntryToList(verbs, HttpVerbs.Options, verbList, "OPTIONS");

            return 
verbList.ToArray();
        
}

La manera en la que utilizamos estos nuevos atributos como era de esperar es la misma, tenemos dos enfoque principales, especificando en el constructor del atributo AcceptVerbsAttribute el tipo de verbo por medio de la enumeración HttpVerbs, o directamente por medio de los atributos HttpPatchAttribute y HttpOptionsAttribute. Esta última opción como podemos observar a continuación es más rápida de escribir y fácil de leer.

        [HttpPatch][HttpOptions]
        
public ActionResult Index()
        {
            ViewBag.Message 
"Modify this template to jump-start your ASP.NET MVC application.";

            return 
View();
        
}

        [AcceptVerbs(HttpVerbs.Patch)]
        [AcceptVerbs(HttpVerbs.Options)]
        
public ActionResult Index()
        {
            ViewBag.Message 
"Modify this template to jump-start your ASP.NET MVC application.";

            return 
View();
        
}

El verbo HTTP PATCH se utiliza para modificar un recurso HTTP. Digamos que con el verbo HTTP PUT podíamos crear o reemplazar un recurso ya existente, pero no modificarlo. Este es el propósito del verbo HTTP PATCH. Si el lector quiere saber más le recomiendo este enlace.

En cuanto al verbo HTTP OPTIONS permite al cliente saber que opciones, requerimientos y capacidades del servidor están asociadas a la comunicación entre el cliente y el servidor. Si deseas profundizar un poco más sobre este verbo, puedes hacerlo aquí.

El libro que me hubiera gustado y el libro que me ha gustado

10. November 2012 08:00 by Oscar.SS in Formación, Lenguajes  //  Tags: ,   //   Comments (0)

El título que he elegido para la reseña de este libro es una simplificación de "El libro que me hubiera gustado cuando empezaba a programar en JavaScript y el libro que me ha gustado ahora que creía que sabía programar en JavaScript". Y es que el autor ha conseguido en 368 páginas de contenido (quitando índices y de más) que el libro sea un completo manual de programación con JavaScript tanto para los que empiezan como para los que ya tienen cierta experiencia.

 

Título: Fundamentos de JavaScript y AJAX
Autor: José Manuel Alarcón
Editorial: Krasis Press
I.S.B.N.: 978-84-939659-2-1
Fecha publicación: 2012
Nº páginas: 397
Nº capítulos: 12 + apéndice
WebSite: CampusMVP

 

Elogios

Los primeros 7 capítulos están dedicados a los fundamentos del lenguaje en sí. Es realmente loable como el autor consigue en tan solo 140 páginas darte todos los conocimientos y herramientas necesarias para comenzar a programar JavaScript conociendo a fondo conceptos como tipos de datos, variables, funciones, operadores, estructuras de control, matrices, y manejo de cadenas de texto y fechas. Incluso el autor se permite el lujo de dar algunas referencias históricas y anécdotas que amenizan la lectura.

En mi opinión esta es la parte más complicada de un libro, en la que se explican los fundamentos, dado que si el lector la encuentra tediosa o difícil de entender, posiblemente abandone la lectura del mismo. Este libro aprueba este examen con un sobresaliente.

Por motivos personales tenía muchas expectativas sobre el capítulo 8. La programación orientada a objetos, el concepto más complicado de entender y también de explicar en este lenguaje, se describe con un estilo muy didáctico y ameno. Sinceramente puedo decir, que antes de comenzar la lectura yo tenía unos fuertes conocimientos sobre el tema y aún así he aprendido no pocas recetas útiles.

Los capítulos 10 y 11, eventos y AJAX respectivamente, han sido con los que más he disfrutado. Tienen un montón de ejemplos prácticos que el programador seguro va a necesitar en su día a día. 

El capítulo 12, errores comunes y depuración, es exquisitamente pragmático. Sin duda el programador encontrará muy interesante sobre todo la sección dedicada al estudio a fondo de la herramienta de depuración del explorador Chrome.

Y por si fuera poco todo lo anterior, todavía el libro tiene un apéndice sobre expresiones regulares que a pesar de ser un tema bastante peliagudo lo he encontrado muy bien explicado y ordenado.

 

Críticas

La verdad es que realmente no tengo ninguna crítica como tal, pero sí tendría que destacar algo en esta sección es que el capítulo 9 dedicado a los fundamentos del BOM y el DOM me ha resultado más aburrido de leer que el resto. Bueno, siendo totalmente rigurosos el capítulo comienza con una reseña histórica de gran valor y didáctica pero después se convierte en una colección de propiedades y definiciones de estas. Aunque no veo como se podría hacer de otro modo.

Y si me pongo muy puntilloso, en el capítulo 8, dedicado a la programación orientada a objetos, en la parte que habla de la herencia con prototipos, quizás he echado en falta algo más de código y menos literatura.

 

Resumiendo

Como comentaba al comienzo de esta reseña, tanto si no has utilizado nunca este lenguaje como si tienes experiencia con él, encontrarás, ejemplos, trucos y conceptos de gran valor. Y dejarme que me repita, en tan solo 368 páginas de contenido real. Esto es lo que más me ha sorprendido. ¡¡Un trabajo sencillamente espectacular!!

¿Qué esperarías de una empresa si todas pagaran lo mismo?

9. October 2012 17:17 by Oscar.SS in Personal  //  Tags: ,   //   Comments (7)

Personalmente una de las preguntas con la que me he sentido menos cómodo cuando he realizado entrevistas de trabajo es ¿qué esperas de una empresa?. Evidentemente espetar algo como "busco la que más pague" está descartado, no es que sea políticamente incorrecto, pero posiblemente te dejaría fuera del proceso de selección al instante. En cualquier caso, es una pregunta que nunca sabes cómo pueden interpretar tu bien intencionada respuesta.

Por otra parte, algo que siempre me ha llamado la atención de la descripción de ofertas que podemos encontrar en cualquier web de empleo, es que todas parecen estar cortadas por el mismo patrón. A ver si os suena algo de esto, "Empresa líder en el sector...", "Empresa joven y dinámica especializada en servicios de consultoría informática...", "Empresa que ofrece servicios de alto nivel tecnológico...", y así un largo etcétera de escribir y no contar nada. Por no hablar de las empresas que ni siquiera se presentan y en seguida comienzan con lo que ellas esperan de ti como tecnólogo, empleado y persona.

El que todas las ofertas sean parecidas, el que ninguna empresa se diferencie positivamente de otra en su presentación, significa que lo único que las diferencia es el salario que ofertan para un determinado puesto. Y cuando la oferta directamente dice "salario a negociar según valía del candidato", entonces se hace literalmente imposible tener una preferencia clara y la mayoría de las veces envías tu CV sin saber realmente si es el tipo de empresa o proyecto que encaja contigo.

Todo lo expuesto anteriormente me ha hecho reflexionar sobre algunos aspectos.

  • ¿Tenemos perfectamente claro como profesionales que buscamos en una empresa a parte del salario?
  • Mejor aún, ¿saben las empresas que buscan los profesionales?. Si no lo saben evidentemente no lo pueden ofrecer y menos aún diferenciarse de la mediocre competencia, lo que explicaría la proliferación de descripciones de ofertas como las que hemos comentado.
  • ¿Tenemos como colectivo profesional una conciencia común y definida sobre este tema o cada uno va a aire?

Por este motivo os propongo hoy discutir sobre este tema contestando a una simple pregunta: ¿Qué esperarías de una empresa si todas pagaran lo mismo?.

Creo que el concepto o la intención están perfectamente claros. Pero por si acaso lo voy a matizar un poco. Poneros en el caso de que todas las empresas del sector ofertaran el mismo salario para un mismo puesto e imaginar, o mejor preguntaros, que característica o propiedad de la empresa te haría decantarte por una en concreto sobre las demás. No tiene porque ser solo una cosa, es posible que tú tengas mil ideas de lo que esperarías de tu empresa.

Si el tema os parece interesante, eso espero, sentiros libres de dejar vuestra opinión por medio de comentarios. Así mismo, si de verdad pensáis que es un tema que pueda interesar a vuestros compañeros de trinchera estaría bien que lo comentaseis entre vosotros o que lo divulgarais por Twitter, FaceBook o como os parezca.

Tirando la primera piedra

Me gustaría trabajar en una empresa que tenga una mentalidad menos provinciana dando más importancia a lo que realmente puedes aportar que a quién conoces.

¡Espero vuestros comentarios! 

Gestión de errores en ASP.NET MVC

2. September 2012 13:49 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (0)

Supongo que no es necesario mencionar lo importante que es la correcta gestión de errores (o excepciones) en nuestras aplicaciones web. Calidad del producto, índice de profesionalidad, SEO, usabilidad, son algunas de las razones para tener muy en cuenta esta parte del desarrollo.

En ASP.NET MVC (en adelante MVC) tenemos varias formas de controlar los errores para evitar que el usuario vea esa "pantalla de la muerte" y en su lugar podamos mostrarle un mensaje más amigable. En este artículo daremos un repaso ligero a cada una de las distintas opciones que tenemos a nuestra disposición.

 

Gestión de errores en ASP.NET

Si, has leído bien, he dicho gestión de errores en ASP.NET y me he comido a posta el MVC. Siempre que trabajemos con MVC debemos tener en cuenta que este se integra dentro del marco de ASP.NET, por lo  tanto, muchos de los conceptos y bondades del framework serán también válidos para MVC. 

En la figura de la derecha (Fuente: Comparing Web Forms And ASP.NET MVC) podemos ver claramente como MVC se integra en la pila de ejecución de ASP.NET. Por cierto, si os interesa ver en detalle el ciclo de ejecución de MVC os recomiendo la lectura de An Introduction to ASP.NET MVC Extensibility.

En cuanto al tema que nos ocupa, el control de errores, en MVC también podremos hacer uso, con leves diferencias, de las mismas posibilidades que tradicionalmete nos ha brindado el framework de ASP.NET.

Es evidente que podemos usar directamente en nuestro código el control estructurado de excepciones con Try/Catch/Finally.

Otra posibilidad es manejando el evento Application_Error() del archivo Global.asax. En este enlace podéis ver un ejemplo que utiliza esta técnica para gestionar errores producidos durante el procesamiento de solicitudes HTTP como 404, 301, etc (HTTP Codes)

Muy conocido también es el manejo de errores mediante configuración del archivo Web.config y su sección CustomErrors. En Internet existen multitud de ejemplos sobre este tema, aunque particularmente no tantos sobre MVC. Es posible que la razón sea que tenemos que realizar un poco de trabajo extra al definir los métodos de acción en los controladores.

    <customErrors mode="On" defaultRedirect="~/Views/Shared/Error.cshtml">
      
<error statusCode="404" redirect="/Errors/NotFound"/>
      <
error statusCode="500" redirect="InternalError"/>
    </
customErrors>

Con cualquiera de las definiciones de rutas anteriores obtendremos un resultado inesperado. MVC utiliza el sistema de routing de ASP.NET para gestionar las solicitudes entrantes por medio de los controladores. Con la configuración anterior, si definimos un controlador llamado ErrorsController y un método de acción denominado NotFound estaremos manejando solamente el error HTTP 404, del resto de rutas ni se entera. Es imprescindible que las rutas sigan el formato /NombreControlador/NombreVista y que codifiquemos los controladores y métodos de acción asociados. Este es el trabajo extra del que hablaba.

Existen también potentes frameworks de terceros que nos pueden ayudar en la gestión de errores y en algunas funcionalidades más (monitoreo, seguimiento, notificaciones, logs, etc). Un ejemplo podría ser ELMAH que, si no me equivoco, en primer lugar se desarrolló para su uso en ASP.NET pero también está disponible para MVC.

 

Gestión de errores en ASP.NET MVC

Ahora si, hablemos de lo que nos interesa. El framework MVC de partida nos ofrece mecanismos para el manejo de excepciones basados en la clase HandleErrorAttribute. De hecho, para activarlo tan solo tendremos que establecer a On o RemoteOnly el atributo mode del elemento <customErrors> en el archivo de configuración, dado que por defecto en el Global.asax el atributo HandleError viene definido como filtro global a toda la aplicación. En este artículo se explica con sumo detalle la utilización de este mecanismo.

La clase HandleErrorAttribute hereda de FilterAttribute e implementa la interfaz IExceptionFilter cuyo único método OnException() es llamado cuando se produce una excepción. Con la herramienta Reflector podemos estudiar el cuerpo de este método en HandleErrorAttribute.

        public virtual void OnException(ExceptionContext filterContext)
        {
            
if (filterContext == null)
            {
                
throw new ArgumentNullException("filterContext");
            
}

            
if (!filterContext.IsChildAction && 
                (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
            {
                Exception innerException 
filterContext.Exception;

                if 
((new HttpException(null, innerException).GetHttpCode() == 500) && 
                    
this.ExceptionType.IsInstanceOfType(innerException))
                {
                    
string controllerName (string)filterContext.RouteData.Values["controller"];
                    string 
actionName (string)filterContext.RouteData.Values["action"];
                    
HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                    
ViewResult result = new ViewResult
                    {
                        ViewName 
= this.View,
                        MasterName 
= this.Master,
                        ViewData 
= new ViewDataDictionary<HandleErrorInfo>(model),
                        TempData 
filterContext.Controller.TempData
                    }
;

                    
filterContext.Result result;
                    
filterContext.ExceptionHandled = true;
                    
filterContext.HttpContext.Response.Clear();
                    
filterContext.HttpContext.Response.StatusCode 500;
                    
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                
}
            }
        }

Al repasar este código lo que más llama la atención es que solo se están gestionando los errores HTTP 500 o errores internos del servidor. Este podría ser el caso de una división por cero (DivideByZeroException), una conversión erronea de tipos (InvalidCastException), o cuando intentamos devolver en un método de acción una vista que no se ha definido (InvalidOperationException).

Si queremos gestionar errores de redireccionamiento del usuario (como HTTP 307; movido temporalmente) o errores de comunicación en la parte del cliente (como HTTP 404; recurso no encontrado) tendremos que hacer uso combinado del los elementos customErrors/error y de la correspondiente codificación de los métodos de acción como hemos visto anteriormente.

Funciones Constructoras en JavaScript

24. January 2012 18:14 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (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.

Recent Comments

Comment RSS

Month List