Objetos

En los objetuna serie de datos en una sola variable que por lo general están asociadas entre si. Es tener múltiples datos en una sola variable. Los datos van separados por coma, cada dato se compone de una propiedad, dos puntos y el valor. A la propiedad también se le llama llave (key). Todo ello encerrados entre llaves ({}).

Declarar un objeto – Object literal

Declarar un objeto tiene la siguiente sintaxis y es llamada object literal:

const nomObjeto = {propiedad:valor, propiedad2:valor2,…np:nv};

Esa declaración de variable cuyo valor está encerrado entre llaves es un indicativo de estar en presencia de un objeto.

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 47,
    altura: "5'9",
    profesion: "Ingeniero Electrónica"
}
console.log(brigzen);

Object Literal Enhancement

La traducción sería algo así como Objeto Literal Mejorado. Con esto agrupas variables de ámbito global y las conviertes en parámetros en objetos sin necesidad de indicar el valor de tales parámetros.

// variable declaration 
var name = "Duke"; 
var color = "Brown"; 
var age = 5; 
  
// Using Object Literal Enhancement 
// Combines all variables into a dog object 
var dog = {name, color, age}; 
console.log(dog); 

La salida sería así:

{
    name:"Duke",
    color:"Brown",
    age:5
}
Hay otra manera de declararlos que se llama Object Constructor que se explica más adelante, va a ir de usar una función.

Acceder a los datos de un objeto

Se accede a los valores de las propiedades en un objeto por medio de lo que llaman sintaxis de punto. Se hace referencia al nombre del objeto, seguido de un punto y luego el nombre de la propiedad o llave.

nomObj.nombrePropiedadDato1;

Veámoslo:

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9",
    profesion: "Ingeniero Electrónica"
}
console.log(brigzen.nombre);
console.log(brigzen .apellido);
console.log(brigzen. edad);
console.log(brigzen . altura);
console.log(brigzen   .   profesion);   
Otra forma opcional
console.log(nomObj['nombreDato1']); // Es muy poco usada.

Crear, editar y eliminar datos en un objeto

Para todos estos casos se utiliza también la sintaxis del punto. Como si se trabajara con variables.

Para crear

Se usa la sintaxis del punto y por medio del signo igual (=), se le asigna un valor. En estos casos se usa al signo = como cuando se trabaja con variables. No confundir con los dos puntos (:) que se usan dentro del objeto para separar las propiedades de sus valores.

nomObj.nuevaPropiedad = valor;

Esto agrega un nuevo dato con su respectiva propiedad o llave y el valor correspondiente.

Para editar

Igualmente si se desea modificar un valor dentro del objeto se usa la sintaxis del punto usando el nombre de la propiedad ya existente que se desea modificar y se le agrega un nuevo valor.

nomObj.propiedad = nuevoValor;

Para eliminar

Con la palabra reservada delete y la sintaxis del punto.

delete nomObj.propiedad;

Abajo un objeto al que se le aplica estos tres casos.

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9",
    profesion: "Ingeniero Electrónica"
} 
console.log(brigzen);
brigzen.hoby = "Ajedrez";
brigzen.edad = 47;
delete brigzen.altura;
console.log(brigzen);

Arriba se agregó el nuevo dato hoby, se editó el dato edad y se eliminó el dato altura.

Pasando datos del objeto a variables

Esto es algo como destructurando un objeto. Lo llaman pasar datos de un objeto a variables. Es como desarmando el objeto. Oficialmente trata sobre acceder a los valores de un objeto y asignarlos a una variable.

Para hacerlo de la manera primitiva, antes de los cambios ECMA6, se creaba una variable nueva usando la sintaxis del punto.

const nomVariable = nomObj.propiedad;

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9",
    profesion: "Ingeniero Electrónica"
}
const nombre = brigzen.nombre;
const apellido = brigzen.apellido;
const edad = brigzen.edad;
const altura = brigzen.altura;
const profesion = brigzen.profesion;

console.log(nombre);
console.log(apellido);
console.log(edad);
console.log(altura);
console.log(profesion);

En el ejemplo anterior he creado una serie de variables a partir de los datos del objeto. Esto ha requerido una serie de líneas de código.

Desestructuración de objetos – Object destructuring

Luego del ECMA 6 tenemos una manera más práctica de crear variables a partir de los datos de un objeto llamada desestructuración.

const { nombrePropiedad1, nombrPropiedad2,…nombrePropiedadN } = nomObj;

Lo anterior crea variables con el nombre de la propiedad y el valor de esa propiedad que se encuentran dentro del objeto indicado. Pero la verdadera ventaja del destructuring es que se pueden crear múltiples variables con los datos del objeto en una sola línea de código.

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
const {nombre, apellido, edad, altura} = brigzen;
console.log(nombre);
console.log(apellido);
console.log(`Tiene ${edad} años`);
console.log(`la altura es de ${altura}`);

El uso del signo = tiene un significado no intuitivo, deja de ser <<igual a>> para ser algo así como <<en base al objeto>>.

Objetos dentro de objetos u objetos anidados

Es intuitivo y el acceso a los datos igualmente se ha solido hacer con la sintaxis del punto.

const nomObj = {propiedad:valor, propiedad2:{subpropiedad1:valor}};

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica",
    proyectoActual: {nombre: "Curso Javascript",
                    duracion: "3 meses",
                    clasificacion: "programacion"},
    trabajos:{  ultimo:     {empresa: "Telefónica Movistar",
                            duracion: 5,
                            cargoIncial: "CCR",
                            cargoFinal: "Soporte Avanzado"},

                penultimo:  {compania: "Lucent Technologies",
                            duracion: 1,
                            cargoInicial: "Ingeniero Aux",
                            ultimoCargo: "Soporte Externo"}
            }                        
}
console.log(brigzen.trabajos.ultimo.empresa);
console.log(brigzen.trabajos.ultimo.cargoFinal);
const ultimaEmpresa = brigzen.trabajos.ultimo.empresa;
const cargoFinalMovistar = brigzen.trabajos.ultimo.cargoFinal;
console.log(`La última empresa donde trabajé fue ${ultimaEmpresa} y
            mi último cargo fue ${cargoFinalMovistar}`);

Desestructuración de objetos anidados

Igualmente en el caso de objetos anidados, la mejor manera de extraer los dato y pasarlos a variables es usando la desestructuración. Pero en estos casos no se usa la sintaxis del punto para adentrarse a los objetos anidados. Para acceder a los datos de un objeto anidado usando la desestructuración debemos hacer apertura de otra desestructuración dentro de la desestructuración inicial; algo así como crear desestructuraciones anidadas para llegar a datos de objetos anidados.

const {propiedad1, propiedad2, objetoAnidado:{propiedad1, propiedad2}} = objeto;

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica",
    proyectoActual: {nombre: "Curso Javascript",
                    duracion: "3 meses",
                    clasificacion: "programacion"},
    trabajos:{  ultimo:     {empresa: "Telefónica Movistar",
                            duracion: 5,
                            cargoIncial: "CCR",
                            cargoFinal: "Soporte Avanzado"},
                penultimo:  {compania: "Lucent Technologies",
                            duracion: 1,
                            cargoInicial: "Ingeniero Aux",
                            ultimoCargo: "Soporte Externo"}
            }                       
}
const {nombre, 
       apellido,
       trabajos,
       trabajos:{ultimo:{empresa, cargoFinal},
                 penultimo,
                 penultimo:{compania, ultimoCargo}
                }
      } = brigzen;

console.log(nombre);
console.log(apellido);
console.log(trabajos);
console.log(empresa);
console.log(cargoFinal);
console.log(penultimo);
console.log(compania);
console.log(ultimoCargo);

Para evitar el scroll he colocado la desestructuración en varias líneas, pero lo correcto es ocupar una sola.

Se puede observar que creo las variables nombre, apellido, luego trabajos que es otro objeto en sí. Luego creo una desestructuración anidada para el objeto trabajos de modo de crear las variables empresa y cargoFinal. Dentro de esa desestructuración anidada creo la variable penultimo que es otro objeto en sí y a su vez una segunda desestructuración anidada para el objeto anidado penultimo, para sacar las variables compania y ultimoCargo.

Edición de un objeto declarado con const

Como se ha podido observar, la edición de una variable tipo objeto se puede hacer incluso si ha sido declarada con const y no con let. Claro está que no podría cambiar por completo el tipo de variable pasando de un objeto a, por ejemplo, un número.

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
console.log(brigzen);
brigzen = 12;
console.log(brigzen);

Arriba se puede observar que me da un error que indica que estoy tratando de variar una constante, nada nuevo, ya que esa variable fue declarada con const. No obstante, puedo editar los datos de un variable tipo objeto así haya sido declarada con const.

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
console.log(brigzen);
brigzen.edad = 47;
console.log(brigzen);

Puedo modificar los datos de un objeto editando, agregando o eliminado datos, aún si ha sido declarada con const.

Métodos para prevenir modificaciones en los objetos

Si queremos que los objetos no puedan ser modificados tal como ocurre cuando declaramos otros tipos de variables con const, podemos hacer uso de algunos métodos, a continuación se describen dos de ellos.

No obstante para que estos métodos funcionen es necesario usar el modo estricto.

El método Object.freeze()

Esto es para que un objeto no pueda ser modificado en absoluto. No se puede agregar más datos y ni editar o eliminar datos existentes.

Object.freeze(object);

"use strict";
const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
Object.freeze(brigzen);
brigzen.edad = 48;
console.log(brigzen);

Object.isFrozen()

Para saber si un objeto está bloqueando con el método Object.freeze().

Object.isFrozen(objeto);

"use strict";
const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
Object.freeze(brigzen);
console.log(brigzen);
console.log(Object.isFrozen(brigzen));

Lo anterior arrojará true o false según esté bloqueada o no el objeto con Object.freeze().

El método Object.seal()

Con este método semi bloqueamos el objeto, es decir, a diferencia de Object.freeze() que bloquea por completo al objeto, el método Object.seal(), bloquea solo la posibilidad de agregar o eliminar propiedades, pero sí permite modificar los valores de las propiedades existentes.

Object.seal(objeto);

"use strict";
const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
console.log(brigzen);
Object.seal(brigzen);
brigzen.peso = 176;
console.log(brigzen);

Si intentamos agregar un dato obtenemos un error que nos indica que no se puede. Pero sí podemos modificar datos ya existentes.

"use strict";
const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica"
}
console.log(brigzen);
Object.seal(brigzen);
brigzen.profesion = "Ingeniero en Electrónica, desarrollador Web y especialista SEO";
console.log(brigzen);

Object.isSealed()

Al igual que con Object.isFrozen() podemos saber si un objeto está bloqueando con el método Object.freeze(), con Object.isSealed podemos saber si un objeto está bloqueado con el método Object.Seal().

Object.isSealed( objeto );

"use strict";
const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    altura: "5'9\"",
    profesion: "Ingeniero Electrónica y SEO"
}
Object.seal(brigzen);
console.log(brigzen);
console.log(Object.isSealed(brigzen));

Lo anterior arrojará true o false según esté bloqueada o no el objeto con Object.seal().

Unir dos objetos

Tenemos dos objetos y queremos crear un solo objeto con los valores de los dos primeros.

Digamos que tenemos

objeto1 = {propiedad1:dato1, propiedad2:dato2};

objeto2 = {propiedad3:dato3, propiedad4:dato4}

Y queremos

objetoTotal = {propiedad1:dato1, propiedad2:dato2, propiedad3:dato3, propiedad4:dato4};

Método Object. assign();

Este parece ser el método clásico para hacer esto antes del ECMA6. Solo es necesario colocar dentro de los paréntesis los objetos que se van a copiar. También mencionar que este es un método para objetos que trabaja con objetos.

const objetoTotal = Object.assign(objeto1, objeto2);

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    dob: "9/18/1975",
    profesion: "Ingeniero Electrónica y SEO"
}
const datosFisicos = {
    contextura: "delgado",
    peso: 176,
    ojos: "oscuros",
    cabello: "marron",
    altura: "5'9\""
}
const datosJuntos = Object.assign(brigzen, datosFisicos);
console.log(brigzen);
console.log(datosFisicos);
console.log(datosJuntos);

El Spread Operator

Esta parece ser la forma moderna y más práctica de hacer esto luego del ECMA6. Los 3 puntos indica que copie el contenido de determinado objeto.

const objetoTotal2 = {…objeto1, …objeto2};

Pero está creando un nuevo objeto y se le está dando valores, entre esos valores pueden ir tanto datos propios de un objeto como el contenido de otros objetos. Eso no se podría hacer con el método Object.assign().

const objectTotal = {propiedad1 : valor1, …objeto1, propiedad2 : valor2, …objeto2};

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    dob: "9/18/1975",
    profesion: "Ingeniero Electrónica y SEO"
}
const datosFisicos = {
    contextura: "delgado",
    peso: 176,
    ojos: "oscuros",
    cabello: "marron",
    altura: "5'9\""
}
const datosJuntos = {...brigzen, ...datosFisicos, hoby:"Ajedrez"};

console.log(brigzen);
console.log(datosFisicos);
console.log(datosJuntos);

Arriba he creado un nuevo objeto con la llave valor hoby:»Ajedrez», pero a su vez con el contenido de otros dos objetos sin necesidad de escribirlos uno por uno. Se podría decir que esta es una manera adicional de colocar contenido dentro de un objeto. Sin tener que estar dándoles nombres a cosas que no alcanzan esa necesidad.

const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    dob: "9/18/1975",
    profesion: "Ingeniero Electrónica y SEO"
}
const datosBrigzen = {
    ...brigzen,
    contextura: "delgado",
    peso: 176,
    ojos: "oscuros",
    cabello: "marron",
    altura: "5'9\"",
    descripción:"Persona muy alegre y carismática"
};
console.log(brigzen);
console.log(datosBrigzen);

Arriba se ha creado un nuevo objeto al que se la ha dado datos propiedad : valor pero uno de ellos son los datos de otro objeto.

La palabra reservada this

Hasta ahora en este artículo se ha mencionado el objeto como un contenedor de datos tipo propiedad : valor. Claro que el uso de solo propiedad : valor es muy usado y práctico según el código que se esté escribiendo. Pero en realidad el uso de un objeto viene dado por una serie de datos y una serie de funciones que van a usar esos datos. Luego, esas funciones serán los métodos del objeto.

Podríamos tener una función como valor de una propiedad en un objeto como se muestra a continuación:

const prod = {nombre: "Monitor",
              precio: 300,
              disponibilidad: true,
              info: function() {console.log(`El ${prod.nombre} tiene un
                                precio de ${prod.precio} dólares.`)}}
prod.info();

La palabra reservada this sirve para hacer referencia al nombre del objeto, por lo que podemos cambiar el código de arriba por el siguiente.

const prod = {nombre: "Monitor",
              precio: 300,
              disponibilidad: true,
              info: function() {console.log(`El precio del ${this.nombre}
                                es de ${this.precio} dólares.`) } }
prod.info();

Por los ejemplos de arriba podríamos determinar que en todo caso no hace falta la palabra reservada this ya que podemos usar directamente el nombre del objeto. Pero ocurre que lo de arriba no es la manera óptima de escribir el código. Hay muchas circunstancias que ameritan en uso de this pero podríamos resumir que, en ese caso, tendremos muchos objetos y la misma función por objeto obviamente no es óptimo.

Luego vendrán las funciones constructoras y más tarde las clases, con todo ello la programación orientada a objetos.

Algo más ideal es como sigue a continuación, se determina una función al principio del código, luego se indica los objetos, luego se inserta esa función en los objetos (con una función constructora este último paso se obviaría).

function calificacion() {
    if (this.gradoInstruccion > 4) {
        console.log(`El ingeniero ${this.nombre} califica para el cargo de gerente`)
    } else {
        console.log(`El ingeniero ${this.nombre} califica para el cargo de director`)
        } }
const brigzen = {
    nombre: "Brigzen",
    apellido: "Coronado",
    edad: 46,
    gradoInstruccion: 5,
    profesion: "Ingeniero Electrónica y SEO"
}
const jorge = {
    nombre: "Jorge",
    apellido: "Caraballo",
    edad: 45,
    gradoInstruccion: 4,
    profesion: "Ingeniero Instrumentación y Programador"
}
brigzen.evaluacion = calificacion;
jorge.evaluacion = calificacion;
console.log(brigzen);
console.log(jorge);
brigzen.evaluacion();
jorge.evaluacion();

En el ejemplo anterior, la función calificación, escrita una sola vez, fue introducida en los dos objetos, luego esta función hizo uso de los datos de los objetos para dar la respuesta deseada, todo ello con la ayuda de la palabra reservada this, ya que cada objeto tiene nombres diferentes.

12 Object Constructor o Función Constructora de Objetos

Esto es una manera dinámica de crear múltiples objetos con las mismas características o parámetros. Digamos que tenemos carros, los parámetros para los carros serán siempre marca, modelo, año, aire acondicionado.

Entonces yo puedo crear a mode Object Literal:

const carro = {
               marca: 'Ford',
               modelo: 'Fiesta',
               year: 2001,
               aa: true
               }

Pero necesito crear muchos objetos para cada modelo, marca y disponibilidad de aire acondicionado o no.

function Carro(dato1, dato2, dato3, dato4) {
                                            this.marca = dato1;
                                            this.modelo = dato2;
                                            this.aa = true;
                                            this.year = dato3;
                  }

const modeloCarro = new Carro( Ford, Fiesta, null, 2001 );

Se recomienda que el nombre de una Object Constructor empiece con la inicial en mayúscula. Entonces procedo a crear esos objetos con la palabra new.

No se puede usar una función de flecha para crear un object constructor. Una función de flecha tiene la particularidad, vaya ud a saber por qué, que no chequea lo que está dentro de las llaves y entonces no se puede usar la palabra reservada this, y el uso de esta palabra reservada es fundamental para la creación del object constructor. La función de flecha busca más en la ventana global.

Me arroja el siguiente Objeto:

Carro {marca: 'Ford', modelo: 'Fiesta', aa: true, year: 2001}
aa: true
marca: "Ford"
modelo: "Fiesta"
year: 2001

Intencionalmente entre dato2 y dato3 dejé un booleano con el valor por defecto en true. Para hacer eso válido cuando declaro el nuevo objeto tengo que dejar esa posición con el valor null, porque de lo contrario no me va a asignar dato3 como año y lo va a dejar como undefined.

13 Tres métodos útiles (según el curso) para los objetos

const producto = {
    nombre: "Monitor 20 pulgadas",
    precio: 30,
    disponible: true
}

Object.keys();

Muestra los parámetros y sus llaves.

console.log(Object.keys(producto));
(3) ['nombre', 'precio', 'disponible']
0: "nombre"
1: "precio"
2: "disponible"
length: 3
[[Prototype]]: Array(0)

Object.values();

Muestra los valores.

console.log(Object.values(producto));
(3) ['Monitor 20 pulgadas', 30, true]
0: "Monitor 20 pulgadas"
1: 30
2: true
length: 3
[[Prototype]]: Array(0)

Object.entries();

Muestra un verguero de objetos por cada uno de los items. Pero no, analizando creo que son un objeto de arrays y cada arrays está compuesto por los parámetros y valores.

console.log(Object.entries(producto));
(3) [Array(2), Array(2), Array(2)]
0: (2) ['nombre', 'Monitor 20 pulgadas']
1: (2) ['precio', 30]
2: (2) ['disponible', true]
length: 3
[[Prototype]]: Array(0)

Listo

Hasta aquí el estudio de los objetos que no tiene para nada algo de dificultad. Es solo saber cómo va la cosa y decir, ok, si dices que es así, pues ok.