preloader

Ampliación de clases incorporadas en JavaScript

Ampliación de clases incorporadas

Las clases integradas en JavaScript, como Array, Map y otras, pueden extenderse para añadir funcionalidades personalizadas.

Por ejemplo, podemos crear una clase PowerArray que hereda del Array nativo:

				
					class PowerArray extends Array {
  isEmpty() {
    return this.length === 0;
  }
}

let arr = new PowerArray(1, 2, 5, 10, 50);
console.log(arr.isEmpty()); // false

let filteredArr = arr.filter(item => item >= 10);
console.log(filteredArr); // [10, 50]
console.log(filteredArr.isEmpty()); // false

				
			

Es interesante notar que métodos nativos como filter, map y otros devuelven nuevos objetos del mismo tipo que el objeto heredado, en este caso, PowerArray. Esto se logra internamente utilizando la propiedad constructor del objeto:

				
					console.log(arr.constructor === PowerArray); // true

				
			

Cuando se llama a arr.filter(), internamente se utiliza arr.constructor para crear la nueva matriz de resultados, no simplemente Array. Esto permite que podamos seguir utilizando métodos personalizados de PowerArray en el resultado.

Podemos personalizar este comportamiento aún más añadiendo un getter estático especial Symbol.species a la clase. Este getter especifica qué constructor JavaScript debe usar internamente para crear nuevas entidades en métodos como map, filter, entre otros.

Si deseamos que los métodos incorporados como map o filter devuelvan matrices regulares en lugar de PowerArray, podemos configurar Symbol.species para devolver Array:

				
					class PowerArray extends Array {
  isEmpty() {
    return this.length === 0;
  }

  static get [Symbol.species]() {
    return Array;
  }
}

let arr = new PowerArray(1, 2, 5, 10, 50);
console.log(arr.isEmpty()); // false

// filter ahora devuelve una matriz estándar utilizando Array como constructor
let filteredArr = arr.filter(item => item >= 10);

// filteredArr ya no es PowerArray, sino Array
console.log(filteredArr.isEmpty()); // Error: filteredArr.isEmpty no es una función

				
			

Como se puede ver, ahora filter devuelve una instancia de Array en lugar de PowerArray. Esto asegura que la funcionalidad extendida no se herede en el resultado.

Otras colecciones como Map y Set funcionan de manera similar, utilizando también Symbol.species para definir su comportamiento de construcción de instancias.

Herencia estática en objetos integrados

A diferencia de las clases personalizadas, los objetos integrados en JavaScript no heredan métodos estáticos entre sí. Por ejemplo, Array y Date, a pesar de que ambos heredan de Object, no comparten métodos estáticos como keys():

				
					// Array y Date no heredan métodos estáticos entre sí
console.log(Array.keys); // undefined
console.log(Date.keys); // undefined

				
			

Aunque Array y Date comparten Object.prototype como su prototipo base, sus objetos no comparten métodos estáticos directamente entre sí. Cada uno tiene su propia implementación independiente.

Esta diferencia en la herencia de métodos estáticos es crucial cuando se trabaja con objetos integrados en comparación con la herencia estándar utilizando extends.

Related Post

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *