Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 4 de octubre de 2011

Blogger invitado

image

Óscar Sotorrío Sánchez

Senior Analyst en Avanade, MCP C#

Eterno aprendiz en esto de las tecnologías .NET y en especial con ASP.NET. Admirador de la filosofía de Internet y entusiasta de los nuevos modelos de negocio que rigen este mundillo.
Blog: oscarsotorrio.com
Los desarrolladores que venimos de lenguajes Orientados a Objetos (OO) podemos encontrarnos con algunos detalles desconcertantes a la hora de trabajar con objetos JavaScript, dado que éstos 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 dinámicamente sus propiedades y le asignamos valores
    cliente.nombre = "Pedro García";
    cliente.direccion = "Calle San Juan, 3, 5º B";
    cliente.fechaNacimiento = new Date(1975, 3, 23);
    cliente.empleoActual = "Soldador";
Como podemos observar, en primer lugar creamos una instancia de Object y a continuación creamos sus propiedades asignándoles directamente 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 sí 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";
Fijaos 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 sí, 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 dirección
    var cliente = new Object();
    cliente.nombre = "Sergio Rodriguez";
    cliente.direccion = direcClient;
    cliente.fechaNacimiento = new Date(1975, 3, 23);
    cliente.empleoActual = "Programador de los buenos";

    //Accedemos a los valores de la dirección
    var suCalle = cliente.direccion.calle;
De hecho, si realmente los objetos son colecciones de otros objetos, ¿que nos impide recorrerlos 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:

Alert mostrando el valor de una propiedad de tipo ObjectAlert mostrando el valor de una propiedad de tipo String

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 Pérez",
        fechaNacimiento: new Date(1973, 12, 13),
        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.

Propiedades sobre el objeto windowCuando 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!


Autor: Óscar Sotorrío Sánchez
Publicado en: Variable not found

16 Comentarios:

Carlos Díez dijo...

Compi eres un crack!!! Me alegro mogollón de la colaboración con otro crack como JM Aguilar, la unión hace la fuerza. Un saludo para los dos.

Marc Rubiño dijo...

Con todos los respetos, no puedes hablar de los objetos en Javascript sin hacer referencias a los prototipos ni a las funciones como objetos.

Tendrías que ampliar el tema con estas cosas que son básicas a la hora de hablar de objetos en JavaScript.

Saludos

josé M. Aguilar dijo...

@Carlos, gracias por tu comentario. Para mí es un placer publicar un post de Óscar, que ya sabes que es un fenómeno.

@Marc, es cierto... pero hay que ir poco a poco. Hay más posts en la recámara para seguir profundizando en el tema :-)

Saludos!

Unknown dijo...

@Marc, yo pensé lo mismo esta mañana, pero tener a Oscar al lado da acceso a información confidencial.. :P

Como intro está genial.. :)

Felicidades Oscar.. good job.

Oscar.SS dijo...

Por alusión...

Está claro que faltan muchos conceptos por comentar pero para un solo post sería demasiado...¡menudo ladrillo!

Y que conste que yo no soy ningún fenómeno de JavaScript ni de nada. Pero creo que es un tema interesante y que muchos desarrolladores (me incluyo) descuidamos.

Solo espero explicar estas "cosas raras" que tiene JavaScript con la mayor simplicidad posible.

Gracias a todos!!

Marc Rubiño dijo...

Claro Oscar, me parece genial tu aportación ahora solo tienes que ir ampliando el tema ;-)

Saludos a todos.

Seldaiendil dijo...

@Jose entiendo que no quieras profundizar en un solo post, pero has hecho afirmaciones falsas que podrían confundir a los desarrolladores que profundicen:

> En JavaScript no disponemos del concepto de clases
El concepto está, no se definen de la forma a la que estamos acostumbrados.

> objeto JavaScript no tiene un conjunto de propiedades y método predefinidos
Falso, claro que lo tiene, toda su cadena de prototipos.

> como sí lo tienen, gracias a las clases, los lenguajes OO
Javascript es OO, y tiene clases.

josé M. Aguilar dijo...

@Seldaiendil, espero que próximos posts profundicen en esos temas que comentas.

Gracias por las puntualizaciones :-)

Un saludo!

Eduardo A.F. dijo...

Cual es la diferencia, ventaja y desventaja de crear objetos con new Object();

var obj = new mifuncion();

o

var obj={};

Óscar.SS dijo...

Hola Eduardo,

La ventaja de utilizar una función constructora es la reutilización de esta para crear multiples objetos sin tener que volver a definir sus propiedades.

Es decir, defines una sola vez en la función constructora las propiedades que tendrán todos los objetos que crearás a partir de la función.

Puedes leer más sobre funciones constructoras aquí: http://www.variablenotfound.com/2011/12/funciones-constructoras-en-javascript.html#more

Un saludo y gracias por comentar.

Victor dijo...

Disculpa que editor usar, para que se vean los posibles propiedades, yo uso sublimetext pero el tuyo cual es?

josé M. Aguilar dijo...

Hola!

Por las capturas del post, diría que es Visual Studio.

Saludos.

Victor dijo...

Una duda mas que no me deja dormir, la verdad estoy aprendiendo javacript en internet por paginas como la tuya (gracias).

supongamos que declaro

var variableUno= 10;

puedo accesar a ella con window.variableUno

Porque la variable es un objetoque cuelga del objeto principal window

Pero si en una funcion declaro una variable como accedo a ella?

function soyFuncion (x,y){
var a = x + y;
return a;
}
como accdedo a la variable a?

soyFuncion.a?

Lo que tambien me a costado entender es el scope.

si hago una variable

var f=10; //soy del objeto window
f = Rojo; //Sigo siendo del bjeto window, solo cambie el valor al fin y al cabo soy una variable

Lo que yo entendi es que si en una funcion se mete esa variable pero sin el var

function otrafunc (){
f="Dado"
}
en reallidad el compilador lo toma como el la anterior variable

como si dijera "a chisss esta ya la declararon es de el objeto window"

josé M. Aguilar dijo...

Hola,

tus cuestiones tienen que ver con el ámbito de visibilidad de las variables.

Si declaras una variable dentro de una función, ésta sólo es visible dentro de ella. Por eso no podrías usar "soyFuncion.a" para acceder a su valor.

Pero si desde dentro de una función usas una variable que no está declarada en ella (es decir, que procede de un ámbito superior), se buscará en el objeto window.

De todas formas, son temas que es importante que aprendas bien. Te recomiendo que busques un buen libro o tutorial donde comiencen desde cero con estos aspectos y puedas controlarlo desde el principio, porque más adelante, en javascript, encontrarás cosas incluso más misteriosas ;)

Un saludo.

Victor dijo...

Muchas gracias, ¿Algun buen libro que recomiendes? Uno en español a ver si lo encuentro por la red, de antemano muchas gracias. estoy sufriendo para entender los clouseres.

De hecho estoy siguiendo un tuto muy didactico solo que me quede trabado en el ejercicio de este capitulo, me podrias hechar la mano, si tienes tiempo? http://nathansjslessons.appspot.com/lesson?id=1055&lang=es

josé M. Aguilar dijo...

Hola!

Este libro está muy bien:
http://www.variablenotfound.com/2012/10/libro-fundamentos-de-javascript-y-ajax.html

Saludos.