Sobes.tech
Middle+

¿Qué sabes sobre los descriptores?

sobes.tech AI

Respuesta de la IA

Los descriptores en JavaScript son objetos que describen diversas propiedades de una propiedad de un objeto, como su valor (value), la posibilidad de escritura (writable), la posibilidad de enumeración (enumerable) y la posibilidad de configuración (configurable). También existen descriptores con getters y setters.

Hay dos tipos de descriptores:

  • Descriptores de datos: Contienen el valor de la propiedad.

    • value: El valor de la propiedad. Puede ser de cualquier tipo de dato válido.
    • writable: Un valor booleano. Si es true, el valor de la propiedad puede ser cambiado (obj.prop = newValue). Por defecto, es false para propiedades de acceso y true para propiedades de datos creadas mediante asignación normal.
    • enumerable: Un valor booleano. Si es true, la propiedad será visible durante la iteración sobre las propiedades del objeto (por ejemplo, en un ciclo for...in o usando Object.keys()). Por defecto, es false para propiedades añadidas con Object.defineProperty y true para propiedades creadas mediante asignación normal.
    • configurable: Un valor booleano. Si es true, las características del descriptor (excepto value y writable cuando cambian de datos a accesorios) pueden ser modificadas, y la propiedad puede ser eliminada. Por defecto, es false para propiedades añadidas con Object.defineProperty (excepto value) y true para propiedades creadas mediante asignación normal. Una vez configurado como no configurable, no puede ser cambiado de nuevo. Puedes disminuir la writable de true a false, pero no viceversa en un getter/setter no configurable.
  • Descriptores de accesorios: Definen funciones que se llamarán al obtener (getter) o establecer (setter) el valor de la propiedad.

    • get: Función que se llama al leer la propiedad. El resultado de esta función se convierte en el valor de la propiedad. No acepta argumentos.
    • set: Función que se llama al escribir en la propiedad. Acepta un argumento, que es el nuevo valor a establecer.
    • enumerable: Un valor booleano (similar a los descriptores de datos).
    • configurable: Un valor booleano (similar a los descriptores de datos).

No se deben mezclar descriptores: una propiedad tiene o value y writable, o get y set.

Los descriptores se usan para gestionar las propiedades de un objeto a un nivel más bajo que la asignación normal, en particular mediante los métodos Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().

Ejemplo de creación de una propiedad con descriptor de datos:

// Crear un objeto vacío
const obj = {};

// Definir la propiedad 'name' con un descriptor de datos
Object.defineProperty(obj, 'name', {
  value: 'Alice',
  writable: false, // La propiedad no puede ser modificada
  enumerable: true, // La propiedad será enumerable
  configurable: false // Las características de la propiedad no pueden ser modificadas, no puede ser eliminada
});

console.log(obj.name); // Mostrará: Alice

// Intento de modificar la propiedad (será ignorado en modo estricto o lanzará error)
obj.name = 'Bob';
console.log(obj.name); // Mostrará: Alice

// Intento de eliminar la propiedad (será ignorado o lanzará error)
delete obj.name;
console.log(obj.name); // Mostrará: Alice

Ejemplo de creación de una propiedad con descriptor de accesorios:

// Crear un objeto con una variable privada
const user = {
  _firstName: 'John', // Variable privada por convención
  _lastName: 'Doe'
};

// Definir la propiedad 'fullName' con un descriptor de accesorios
Object.defineProperty(user, 'fullName', {
  get() {
    // Getter: devuelve el nombre completo
    return `${this._firstName} ${this._lastName}`;
  },
  set(value) {
    // Setter: divide el nombre completo en partes y actualiza las variables privadas
    const parts = value.split(' ');
    this._firstName = parts[0];
    this._lastName = parts[1];
  },
  enumerable: true, // La propiedad será enumerable
  configurable: true // Las características de la propiedad pueden ser modificadas, la propiedad puede ser eliminada
});

console.log(user.fullName); // Mostrará: John Doe

user.fullName = 'Peter Pan';
console.log(user._firstName); // Mostrará: Peter
console.log(user._lastName); // Mostrará: Pan
console.log(user.fullName); // Mostrará: Peter Pan

El uso de descriptores permite crear propiedades inmutables, propiedades con cálculo perezoso, propiedades con control de acceso (getters/setters) y gestionar más flexible el comportamiento de los objetos.