En una class js, ¿cuál es la mejor manera de llamar a super pasar todos los arguments hasta la class principal?

En las classs JavaScript ES6, ¿cuál es el mejor enfoque para llamar a un super en el constructor pasando todos los arguments a la class padre?

Se me ocurrió este model usando el operador de difusión, ¿hay algún inconveniente en este enfoque?

class Parent { constructor(a, b, c){ console.log("a:", a); console.log("b:", b); console.log("c:", c); } } class Child extends Parent { constructor(){ super(...arguments); this.doMyStuff(); } } let child = new Child("Param A", "Param B", "Param C") 

Hagamos esa vieja cosa de Pros y contras:

Pros

  1. Si cambia la cantidad de arguments que los Parent aceptan, no es necesario que cambie Child . Todavía tiene que cambiar el código usando Parent or Child si los arguments cambian lo afecta, pero Child se actualiza automáticamente.

  2. (Muy débil.) Brevedad.

Contras

  1. Pérdida de claridad ¿Cuáles son los arguments para Child ? Mitigación: Documentación.

  2. Las herramientas no pueden indicarle los nombres de los arguments secundarios si no saben cuáles son; si la expresión se generalizó, las herramientas podrían analizar el código y resolverlo, pero no creo que sea probable. Podría mitigar eso declarando los arguments incluso si no los usa, pero luego pierde Pro # 1 arriba.

  3. La arity de Child ( Child.length ) es 0 cuando en efecto es 3 . Nuevamente podría mitigarse declarando los arguments, pero nuevamente perderá Pro # 1.

Neutral

  1. Para evitar posibles problemas de performance con los arguments , debe utilizar el modo estricto (no está en ese código a less que esté en un module). (Debido a que el modo estricto elimina el enlace entre los arguments y los arguments declarados). Pero de todos modos deberías estar usando el modo estricto. 🙂

Nota al margen : Bergi hizo la shiny observación de que puedes evitar los arguments usando en su lugar " arguments en reposo":

 constructor(...args) { super(...args); } 

Puede combinar la desestructuración con params por defecto. Actualmente lo estoy haciendo así:

 class Parent { constructor(args = {}){ //destructure what you need here let { a = "default a", b = "default b", c = "default c" } = args this.a = a this.b = b this.c = c } } class Child extends Parent { constructor(args = {}){ //pass args object super(args) //destructure what you need here let { d = "default d", e = "default e" } = args this.d = d this.e = e } } let parent = new Parent({ a: "Param A", b: "Param B", c: "Param C" }) let child = new Child({ a: "Param A", e: "Param E", c: "Param C" }) console.log(parent) console.log(child) 

De esta manera, cambia un poco la statement de object, ya que siempre pasa variables como un único object args.

Sin embargo, puede considerar search un object tipo, ya que no arrojará un error si va a pasar algo más, sino que simplemente usaría los valores pnetworkingeterminados. Pero creo que eso debería contar como comportamiento anticipado.

De la misma manera, args = {} maneja el caso sin arguments, pero tampoco es estrictamente necesario, pero es un buen hábito, si por ejemplo accidentalmente extraes algo de args más tarde de manera no destructiva.

Aquí hay un contenedor: JSBin

¿Qué ganas con el enfoque genérico?

 class Child extends Parent { constructor(a,b,c){ super(a,b,c); this.doMyStuff(); } } 

ya no es su versión sino explícita en lo que está esperando y transmitiendo, y por lo tanto es más fácil de entender para el lector casual de su código fuente.