Original article: Objects in JavaScript – A Beginner's Guide

Si declaras varios variables para contener diferentes valores, esto puede hacer que su programa se vuelva desordenado y torpe.

Por ejemplo, si necesitas almacenar tres características cada una para 10 personas, teniendo 30 variables declaradas individualmente puede hacer que su programa parezca menos organizado.

Así que necesitas una forma de agrupar valores con características similares para que su código sea más legible. Y en JavaScript, los objetos funcionan bien para este propósito.

A diferencia de otros tipos de datos, los objetos pueden almacenar valores complejos. Debido a esto, JavaScript depende en gran medida de ellos. Así que es importante que se familiarice con lo que es un objeto, cómo crear uno y cómo puede usarlo antes de profundizar el aprendizaje de JavaScript.

Este artículo le presentará los conceptos básicos de los objetos, la sintaxis de los objetos, los diferentes métodos para crear objetos, cómo copiar objetos y cómo iterar sobre un objeto.

Para aprovechar al máximo este artículo, debes tener al menos un conocimiento básico de JavaScript, en particular las variables, funciones y tipos de datos.

¿Qué son los objetos en JavaScript?

Un objeto es un tipo de datos que puede incluir colecciones de pares clave-valor.

Una diferencia importante entre un objeto y otros tipos de datos, como cadenas y números en JavaScript, es que un objeto puede almacenar diferentes tipos de datos como sus valores. Por otro lado, los tipos de datos primitivos como números y cadenas pueden almacenar solo números y cadenas, respectivamente, como sus valores.

La clave, también conocida como nombre de propiedad, suele ser una cadena. Si se utiliza cualquier otro tipo de datos como nombre de propiedad que no sean cadenas, se convertirá en una cadena.

Puede visualizar un objeto como un estante de usos múltiples que contiene espacio para sus dispositivos y adornos, así como un espacio de almacenamiento para libros y archivos.

shelf1-2
Un estante con varios artículos en él.

La característica más reconocible de un objeto son los corchetes que contienen el par clave-valor.

const objetoVacio = {};
console.log(typeof objetoVacio); //'object'

El contenido de un objeto puede consistir en variables, funciones o ambos. Variables que se encuentran en los objetos son propiedades, mientras que las funciones son métodos. Los métodos permiten que los objetos usen las propiedades dentro de ellos para realizar algún tipo de acción.

Por ejemplo, en el código de muestra a continuación, objeto1.usuario, objeto1.nacionalidad y objeto1.profesion son propiedades de objeto1 mientras que objeto1.miBiografia() es un método:

const objeto1 = {
  usuario: "Alex",
  nacionalidad: "Nigeria",
  profesion: "Ingeniero de Software",
  miBiografia() {
    console.log(
      `Mi nombre es ${this.usuario}. Soy un ${this.profesion} de ${this.nacionalidad}`
    );
  },
};
console.log(objeto1.usuario); // Alex
console.log(objeto1.nacionalidad); // Nigeria
console.log(objeto1.profesion); // Ingeniero de Software
console.log(objeto1.miBiografia()); // Mi nombre es Alex. Soy un Ingeniero de Software de Nigeria

Las claves en el código de muestra anterior son usuario, nacionalidad y profesion, mientras que sus valores son los valores de cadena que vienen después de los dos puntos. Además, observa el uso de la palabra clave this. La palabra clave this simplemente se refiere al objeto en sí.

Como se mencionó anteriormente en este artículo, el valor de una propiedad puede ser cualquier tipo de datos. En el siguiente código de ejemplo, los valores son
arreglos y objetos:

 const objeto2 = {
  usuario: ["Alex", "James", "Mohammed"],
  profesión: {
    alex: "Ingeniero de Software",
    james: "Abogado",
    mohammed: "Escritor técnico",
  },
};
console.log(objeto2.usuario); // ['Alex', 'James', 'Mohammed']
console.log(objeto2.profesión); // {alex: "Ingeniero de Software", james: "Abogado", mohammed: "Escritor técnico"}

Cómo acceder a objetos y crear nuevas propiedades o métodos de objeto en JavaScript

Hay dos formas de acceder a los objetos: notación de puntos y notación de corchetes. En el código de muestra anterior, usamos la notación de puntos para acceder a las propiedades y métodos en el objeto1 y el objeto2.

Además, para crear nuevas propiedades y métodos después de la declaración de un objeto, puedes usar la notación de puntos o la notación de corchetes. Solo tienes que indicar la nueva propiedad y darle un valor.

Por ejemplo, podemos agregar nuevas propiedades a objeto2 de este modo:

objeto2.edad = [30, 32, 40];
objeto2["resumen"] = `Objeto2 tiene ${objeto2.usuario.length} usuarios`;
console.log(objeto2);
/*
{
    "usuario": [
        "Alex",
        "James",
        "Mohammed"
    ],
    "profesion": {
        "alex": "Ingeniero de Software",
        "james": "Abogado",
        "mohammed": "Escritor técnico"
    },
    "edad": [
        30,
        32,
        40
    ],
    "resumen": "Objeto2 tiene 3 usuarios"
}
*/

De manera similar, puedes usar cualquier notación para cambiar el valor de un objeto:

objeto2.usuario = ["jane", "Williams", "John"];
objeto2["edad"] = [20, 25, 29];
console.log(objeto2.usuario); //['jane', 'Williams', 'John']
console.log(objeto2.edad); //[20, 25, 29]

Aunque la notación de puntos es la más utilizada para acceder a las propiedades y métodos de un objeto, tiene algunas limitaciones. Veámoslos ahora.

No puedes usar valores como nombres de propiedades con notación de puntos

Si deseas utilizar el valor de un variable como nombre de propiedad en su objeto, debes utilizar la notación de corchetes y no la notación de puntos. Si el valor de el variable se define en tiempo de ejecución o no es irrelevante.

El tiempo de ejecución es una fase de un programa de computadora en la que el programa se ejecuta en un sistema de computación.

Por ejemplo:

const objeto3 = {};
const aparato = prompt("ingresa un tipo de aparato");
objeto3[aparato] = ["jbl", "sony"];
console.log(objeto3); // (respuesta ingresada en el prompt): ["jbl","sony"] observa que el nombre de la propiedad es el valor que ingresa en la respuesta al mensaje del prompt

Si defines el valor de el variable en su código, y usas la notación de puntos para establecer ese valor como un nombre de propiedad de su objeto, la notación de puntos creará una nueva propiedad con el nombre de el variable en lugar del valor de el variable.

const computadora = "marcas";
objeto3.computadora = ["hp", "dell", "apple"];
console.log(objeto3.marcas); // undefined
console.log(objeto3.computadora); // ['hp', 'dell', 'apple']

objeto3[computadora] = ["hp", "dell", "apple"];
console.log(objeto3.marcas); // ['hp', 'dell', 'apple']

Nota la omisión de comillas dentro de los corchetes. Esto se debe a que los paréntesis tomaron un variable.

No puedes usar propiedades de varias palabras con notación de puntos

Cuando el nombre de la propiedad es una cadena de varias palabras, la notación de puntos es insuficiente. Por ejemplo:

objeto3.usuario altura = [5.6, 5.4, 6.0];
Console.log(objeto3.usuario altura); //SyntaxError

Se produce un error de sintaxis porque JavaScript lee el comando como  objeto3.usuario, pero no reconoce la altura de la cadena, entonces devuelve un error de sintaxis.

Cuando se utiliza la notación de puntos para acceder a objetos, se aplican las reglas habituales de declaración de un variable. Esto significa que si deseas utilizar la notación de puntos para acceder a un objeto o crear una propiedad, el nombre de la propiedad no debe comenzar con un número, no debe incluir espacios y solo puede incluir los caracteres especiales $ y _.

Para evitar este tipo de error, debes usar la notación de corchetes. Por ejemplo, puedes corregir el código de muestra anterior de esta manera:

objeto3["usuario altura"] = [5.6, 5.4, 6.0];  
console.log(objeto3["usuario altura"]); //[5.6, 5.4, 6]

Cómo crear objetos con el constructor de objetos en JavaScript

Hay dos métodos por cuál puedes crear un objeto: un objeto literal y el constructor de objetos. Los objetos usados hasta ahora como ejemplos en este artículo son objetos literales. Objetos literales funcionan bien si deseas crear un solo objeto.

Pero si deseas crear más de un objeto, siempre es mejor usar el constructor de objetos. Esto le permite evitar repeticiones innecesarias en su código y también facilita cambiar las propiedades de su objeto.

Básicamente, los constructores son funciones cuyos nombres suelen estar en mayúsculas. El uso de mayúsculas en el nombre de un constructor no tiene ningún efecto en el objeto. Es sólo un medio de identificación.

Puedes usar un constructor para crear un nuevo objeto llamando al constructor con la palabra clave new. La palabra clave new creará una instancia de un objeto y vinculará la palabra clave this al nuevo objeto.

Como se mencionó anteriormente en este artículo, la palabra clave this es una referencia al objeto en sí.

Un ejemplo de un constructor de objetos es:

function Perfil(nombre, edad, nacionalidad) {
  this.nombre = nombre;
  this.edad = edad;
  this.nacionalidad = nacionalidad;
  this.biografia = function () {
    console.log(
      `Mi nombre es ${this.nombre}. Tengo ${this.edad} años de edad. Soy de ${this.nacionalidad}.`
    );
  };
}

const oladele = new Perfil("Oladele", 50, "Nigeria");
console.log(oladele.biografia()); // Mi nombre es Oladele. Tengo 50 años de edad. soy de Nigeria.

Cómo crear copias de objetos en JavaScript

A diferencia de los tipos de datos primitivos, como cadenas y números, la asignación de un objeto existente a otro variable no producirá una copia del original sino una referencia en la memoria.

Lo que esto significa es que tanto el objeto original como los objetos posteriores creados al asignar el objeto original como un valor hacen referencia al mismo elemento en la memoria.

Esto significa que un cambio en el valor de cualquiera de los objetos también provocará un cambio en los demás. Por ejemplo:

let x = 10;
let y = x;
x = 20;
console.log(x); // 20
console.log(y); // 10

let objeto4 = {
  nombre: "Alex",
  edad: 40,
};
let objeto5 = objeto4;
console.log(objeto5); // {nombre: 'Alex', edad: 40}
objeto4.nombre = "Jane";
console.log(objeto5); // {nombre: 'Jane', edad: 40}
console.log(objeto4 === objeto5); // true

Para crear una copia de un objeto, puedes utilizar el operador de propagación.

¿Qué es el operador de propagación?

El operador de propagación está representado por tres puntos ... . Puedes utilizar el operador de propagación para copiar los valores de cualquier iterable incluyendo objetos.

Un iterable es un objeto que se puede repetir o iterar con la ayuda de un for...bucle. Los ejemplos de iterables incluyen objetos, arreglos, conjuntos, cadenas, etc.

Para usar el operador de propagación, debes anteponerlo al objeto del que deseas copiar. Por ejemplo:

let objeto6 = {...objeto5}; 
objeto5.nombre = "Willaims"; 
console.log(objeto5); //{nombre: 'Willaims', edad: 40}
console.log(objeto6); //{nombre: 'Jane', edad: 40}
console.log(objeto5 === objeto6); //false

Como puedes ver, a diferencia del ejemplo de código anterior, donde un cambio en el objeto4 causó un cambio en el objeto5, el cambio en el objeto6 no resultó en un cambio en el objeto5.

Cómo utilizar el método Object.assign()

El método Object.assign() copia todas las propiedades enumerables de un objeto en otro y luego devuelve el objeto modificado.

El método toma dos parámetros. El primer parámetro es el objeto de destino que toma las propiedades copiadas. El segundo parámetro es el objeto de origen que tiene las propiedades que desea copiar. Por ejemplo :

let objeto7  = Object.assign({}, objeto6); 
console.log(objeto7); //{nombre: 'Jane', edad: 40}
console.log(objeto7); //{nombre: 'Jane', edad: 40}

console.log(objeto6 === objeto7); //false
objeto6.edad = 60
console.log(objeto6); //{nombre: 'Jane', edad: 60}
console.log(objeto7); //{nombre: 'Jane', edad: 40}

Puedes ver en el código de ejemplo anterior que un cambio en el valor de la propiedad de edad del objeto6 no provocó un cambio en el valor de la propiedad de edad del objeto7.

Ten en cuenta que tanto el operador de propagación como el método Object.assign() solo pueden hacer una copia superficial de un objeto.

Esto significa que si tienes objetos o arreglos profundamente anidados en tu objeto de origen, solo las referencias a dichos objetos se copian en el objeto de destino. Entonces, un cambio en el valor de cualquiera de los objetos profundamente anidados provocaría un cambio en el valor del objeto profundamente anidado del otro. Por ejemplo:

let objetoX = {
  nombre: "Mary",
  edad: 40,
  aparato: {
    marca: ["apple", "sony"],
  },
};

let objetoY = { ...objetoX };
objetoY.nombre = "Bianca";
objetoY.aparato.marca[0] = "hp";
console.log(objetoX);
/*
{
    "nombre": "Mary",
    "edad": 40,
    "aparato": {
        "marca": [
            "hp",
            "sony"
        ]
    }
}
*/

console.log(objetoY);
/*
{
    "nombre": "Bianca",
    "edad": 40,
    "aparato": {
        "marca": [
            "hp",
            "sony"
        ]
    }
}
*/

El código de muestra anterior realizó las siguientes acciones:

  1. Creó un objeto llamado objetoX.
  2. Le dio tres propiedades al objetoX: nombre, edad y aparato.
  3. Le dio a la propiedad de aparato del objetoX un objeto como su valor.
  4. Le dio al valor de objeto de la propiedad de aparato una propiedad de marca.
  5. Le dio a la propiedad de marca un arreglo como su valor.
  6. Copio las propiedades del objetoX en el objetoY con el uso del operador de propagación.
  7. Cambió el valor de la propiedad de nombre del objetoY a Mary.
  8. Cambió el primer elemento en el valor de el arreglo de la propiedad de la marca de apple a hp.

En el código de muestra, el valor de el arreglo es un objeto profundamente anidado. Observa que un cambio en el valor de la propiedad de nombre del objetoY no provocó un cambio en el valor de la propiedad de nombre del objetoX. Pero un cambio en el objeto profundamente anidado del objetoY provocó un cambio similar en el objeto profundamente anidado del objetoX.

Cómo Iterar Sobre Objetos en JavaScript

Use un bucle for...in para iterar sobre un objeto y seleccionar sus propiedades. La sintaxis del bucle for..in es la siguiente:

for(let llave in objeto) {
    //realizar acción(es) para cada llave
}

La palabra clave llave en el sintaxis anterior es un parámetro para las propiedades. Así que puedes reemplazarlo con cualquier palabra de tu elección. Reemplace la palabra clave del objeto con el nombre del objeto sobre el que desea iterar. Por ejemplo:

let objetoZ = {
  nombre: "Ade",
  Pronombre: "el",
  edad: 60,
};
for (let propiedad in objetoZ) {
  console.log(`${propiedad}: ${objetoZ[propiedad]}`);
}
/* 
nombre: Ade
Pronombre: he
edad: 60
*/

Observa el uso de la notación de corchetes en el bucle para obtener los valores de la propiedad. El uso de la notación de puntos en lugar de la notación de corchetes devolvería undefined.

Conclusión

En JavaScript, los objetos son probablemente el tipo de datos más importante. Los conceptos de programación como la programación orientada-a-objetos funcionan según el principio de aprovechar la flexibilidad de los objetos para almacenar valores complejos y su capacidad distintiva de interactuar con propiedades y métodos dentro del objeto.

Este artículo establece una base sólida para comprender conceptos tan avanzados al explicar los conceptos básicos de los objetos.