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.

En ECMAScript 2020 (ES11), introducido en 2020, se introdujo el uso de # para definir campos privados dentro de las clases. Esto proporciona un método más claro que la convención tradicional de privacidad en JavaScript (por ejemplo, nombres de variables que comienzan con un guion bajo). Esto proporciona una manera más clara, reemplazando las convenciones privadas tradicionales de JavaScript (como nombres de variables que comienzan con un guion bajo).

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

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.

1// Cannot access private property directly
2console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class

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

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.

1// Cannot access private method directly
2counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class

Ventajas y consideraciones de las propiedades privadas

Ventaja

  • 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.

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

La encadenación opcional es una sintaxis muy útil en JavaScript para acceder a propiedades de objetos anidados profundamente. 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

La encadenación opcional se puede usar colocando un ? antes del . o de la notación de corchetes utilizada para acceder a las 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
  • De esta manera, también puedes acceder a los elementos de un arreglo utilizando el encadenamiento opcional.

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
  • Como se muestra en este ejemplo, también se puede aplicar a las llamadas de función.

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 OR lógico trata valores como false, 0 y '' como falsos, mientras que el operador de fusión nula utiliza el valor predeterminado solo cuando el valor 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