Características adicionales de las clases en JavaScript

Características adicionales de las clases en JavaScript

En este artículo, explicaremos las características adicionales de las clases en JavaScript.

YouTube Video

Características adicionales de las clases en JavaScript

Propiedades privadas en JavaScript

En JavaScript, las propiedades privadas son propiedades que solo son accesibles dentro del objeto o clase. Esto permite un diseño de código más seguro y robusto al proporcionar encapsulación, de modo que no sea posible la modificación o referencia directa desde código externo.

Introducido en ECMAScript 2020 (ES11) en 2020, se introdujo el uso de # (almohadilla) para definir campos privados dentro de una clase. Esto proporciona una manera más clara, reemplazando las convenciones privadas tradicionales de JavaScript (como nombres de variables que comienzan con un guion bajo).

Ventajas de las propiedades privadas

A continuación se presentan las ventajas de las propiedades privadas.

  • Encapsulación: Oculta el estado interno del exterior y mantiene la consistencia de los datos.
  • Seguridad: Evita que las propiedades sean modificadas involuntariamente por código externo.
  • Mejor Mantenibilidad: Oculta la implementación de objetos o clases y aclara la interfaz expuesta al exterior.

Cómo usar propiedades privadas

Definiendo propiedades privadas en las clases

Los campos privados se definen utilizando un nombre que comienza con #. Este campo no puede ser accedido directamente desde instancias de la clase o sus subclases.

 1class Person {
 2    // Define private property
 3    #name;
 4
 5    constructor(name) {
 6        this.#name = name;
 7    }
 8
 9    // Method to access the private property
10    getName() {
11        return this.#name;
12    }
13
14    // Method to change the private property
15    setName(newName) {
16        this.#name = newName;
17    }
18}
19
20const john = new Person("John");
21console.log(john.getName()); // John
22
23// Cannot access private property directly
24console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class

En el código anterior, #name es una propiedad privada que no puede ser accedida directamente desde fuera de la clase Person. Solo puedes acceder o cambiar el nombre a través de los métodos getName y setName.

Definiendo métodos privados

Al igual que las propiedades privadas, los métodos privados también se definen utilizando un nombre que comienza con #. Los métodos privados solo pueden ser llamados desde dentro de la clase.

 1class Counter {
 2    #count = 0;
 3
 4    increment() {
 5        this.#count++;
 6        this.#logCount(); // Calling private method
 7    }
 8
 9    // Private method
10    #logCount() {
11        console.log(`Current count: ${this.#count}`);
12    }
13}
14
15const counter = new Counter();
16counter.increment(); // Current count: 1
17
18// Cannot access private method directly
19counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class

Aquí, #logCount se define como un método privado y no se puede acceder desde fuera de la clase. Este método se utiliza solo dentro de la clase.

Ventajas y consideraciones de las propiedades privadas

Ventaja

  • Dado que no se puede acceder directamente desde fuera de la clase, se evitan cambios u operaciones no intencionados.
  • Debido a que las partes no visibles desde el exterior pueden ocultarse bien, puedes gestionar claramente las partes que expones como una API.

Notas

  • Debido a que los campos privados están completamente ocultos desde fuera de la clase, las pruebas y la depuración pueden volverse difíciles. Por lo tanto, es importante proporcionar una API que pueda ser probada exhaustivamente en la etapa de diseño.
  • Los campos privados se comportan de manera diferente a otras partes de JavaScript con características basadas en prototipos porque son únicos para cada instancia.

Implementación seudónima tradicional de propiedades privadas

Antes de la introducción de los campos privados utilizando #, JavaScript no tenía una sintaxis oficial para las propiedades privadas. Por lo tanto, en el pasado, las propiedades pseudo-privadas se implementaban de las siguientes maneras.

Convención del uso de guiones bajos

Los desarrolladores indicaban convencionalmente 'privado' anteponiendo un guion bajo al nombre de la variable.

 1class Car {
 2    constructor(brand) {
 3        this._brand = brand; // Using an underscore to indicate private
 4    }
 5
 6    getBrand() {
 7        return this._brand;
 8    }
 9}
10
11const car = new Car("Toyota");
12console.log(car.getBrand()); // Toyota
13console.log(car._brand); // Toyota (Accessible from outside)

Este método es solo una 'convención' y, en la práctica, las propiedades aún pueden ser accesadas desde fuera.

Implementación de propiedades privadas usando cierres

También es posible lograr propiedades privadas usando closures con el alcance de las funciones.

 1function createPerson(name) {
 2    let _name = name; // Private variable within function scope
 3
 4    return {
 5        getName: function() {
 6            return _name;
 7        },
 8        setName: function(newName) {
 9            _name = newName;
10        }
11    };
12}
13
14const person = createPerson("Alice");
15console.log(person.getName()); // Alice
16person.setName("Bob");
17console.log(person.getName()); // Bob
18
19// Cannot access directly from outside
20console.log(person._name); // undefined

Con este método, la variable _name está encerrada dentro del alcance de la función y no se puede acceder directamente desde fuera.

Resumen

Las propiedades privadas en JavaScript son muy efectivas para proporcionar encapsulación en el diseño de clases y objetos, ayudando a proteger los datos de manera segura. La notación # para campos privados introducida en ES2020 proporciona un método más claro y seguro de gestión de privacidad en comparación con las convenciones tradicionales y los closures.

Encadenamiento Opcional en JavaScript

El encadenamiento opcional (Optional Chaining) es una sintaxis muy útil en JavaScript para acceder a propiedades de objetos profundamente anidados. Mejora la legibilidad y el mantenimiento del código al permitir un acceso seguro sin tener que comprobar individualmente la existencia de propiedades específicas.

Sintaxis básica del Encadenamiento Opcional

El encadenamiento opcional se puede usar colocando ? antes del punto (.) o de la notación de corchetes utilizada para acceder a propiedades. Esta notación devuelve undefined cuando una propiedad recorrida es null o undefined, permitiendo que el programa continúe procesándose de manera segura sin arrojar un error.

Ejemplo:

 1const user = {
 2    name: 'John',
 3    address: {
 4        street: '123 Main St',
 5        city: 'New York'
 6    }
 7};
 8
 9// Without using optional chaining
10const city = user && user.address && user.address.city;
11console.log(city);  // New York
12
13// Using optional chaining
14const cityWithOptionalChaining = user?.address?.city;
15console.log(cityWithOptionalChaining);  // New York

En este ejemplo, estamos accediendo a la propiedad address y a su propiedad city del objeto user. Sin usar el encadenamiento opcional, necesitarías realizar múltiples verificaciones de existencia, pero con el encadenamiento opcional puedes acceder a la propiedad de manera segura con una sola declaración.

Uso del Encadenamiento Opcional con arreglos y funciones

El encadenamiento opcional es aplicable no solo a propiedades de objetos, sino también a elementos de arrays y llamadas a funciones.

Ejemplo con arreglos:

1const users = [{ name: 'Alice' }, { name: 'Bob' }];
2
3// Accessing the non-existent third element
4const thirdUser = users[2]?.name;
5console.log(thirdUser);  // undefined

Ejemplo con funciones:

 1const user = {
 2    greet: function() {
 3        return 'Hello!';
 4    }
 5};
 6
 7// Call the function only if greet exists
 8const greeting = user.greet?.();
 9console.log(greeting);  // Hello!
10
11// Return undefined if greet does not exist
12const nonExistentGreeting = user.nonExistentMethod?.();
13console.log(nonExistentGreeting);  // undefined

Combinación del Encadenamiento Opcional con valores predeterminados

Al usar el encadenamiento opcional, es común usar el operador lógico OR (||) o el operador de fusión de nulos (??) para especificar valores por defecto si una propiedad no existe.

Ejemplo:

 1const user = {
 2    name: 'John',
 3    address: {
 4        city: 'New York'
 5    }
 6};
 7
 8// Set a default value for a non-existent property
 9const state = user?.address?.state || 'Unknown';
10console.log(state);  // Unknown
11
12// Example using the nullish coalescing operator
13const zipCode = user?.address?.zipCode ?? '00000';
14console.log(zipCode);  // 00000

El operador || trata false, 0, '', etc., como valores falsy, mientras que el operador ?? solo usa el valor por defecto si el operando es null o undefined.

Beneficios del Encadenamiento Opcional

  • Acceso seguro a objetos anidados: Al usar el encadenamiento opcional, ya no necesitas realizar verificaciones explícitas de existencia, haciendo el código más conciso.
  • Evitar errores: Puede prevenir errores en tiempo de ejecución incluso si una propiedad es null o undefined.
  • Mejora en la legibilidad y el mantenimiento: Especialmente cuando se trata de muchos objetos anidados, la legibilidad del código mejora considerablemente.

Precauciones con el Encadenamiento Opcional

  • El uso frecuente del encadenamiento opcional puede ser un indicio de que el diseño de la estructura de datos es demasiado complejo. Deberías esforzarte por un modelo de datos simple.
  • Dado que algunos navegadores antiguos y motores de JavaScript no lo soportan, puede que necesites usar polyfills o transpilers.

Conclusión

El encadenamiento opcional es una característica poderosa que simplifica el acceso seguro a propiedades y funciones de objetos anidados en JavaScript. Es particularmente efectivo al acceder a estructuras de datos profundamente anidadas, contribuyendo a la prevención de errores y mejorando la legibilidad del código.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video