extended classes in javascript with ecmascript6

5

I have a base class ( Persona , which implements some methods and in its constructor accepts parameters. is the following

class Persona
{
    constructor (nombre, apellido)
    {
        this.nombre = nombre;
        this.apellido = apellido;
    }

    muestraNombre()
    {
        return this.nombre;
    }
    cambiaNombre(nuevoNombre)
    {
        this.nombre = nuevoNombre;
    }

    muestraApellido()
    {
        return this.apellido;
    }
    cambiaApellido(nuevoApellido)
    {
        this.apellido = nuevoApellido;
    }
}

I also have another class ( Trabajador ) that inherits from Persona

class Trabajador extends Persona
{
    constructor(nombre, apellido, nombreEmpresa, direccionEmpresa)
    {
        this.nombre = nombre;
        this.apellido = apellido;
        this.nombreEmpresa = nombreEmpresa;
        this.direccionEmpresa = direccionEmpresa;
    }

    muestraNombreEmpresa()
    {
        return this.nombreEmpresa;
    }
    cambiaNombreEmpresa(nuevoNombreEmpresa)
    {
        this.nombreEmpresa = nuevoNombreEmpresa;
    }

    muestraDireccionEmpresa()
    {
        return this.direccionEmpresa;
    }
    cambiaDireccionEmpresa(nuevoDireccionEmpresa)
    {
        this.direccionEmpresa = nuevoDireccionEmpresa;
    }

}

When I create a new instance of Persona , it does it without problems

var perso = new Persona("pedro", "perez");

but when I try to instantiate class Trabajador :

var traba = new Trabajador("Juan", "Perez", "Mi Empresita", "Aqui Mismito");

gives me the following error

   Uncaught ReferenceError: this is not defined
    at Trabajador (Ejercicio 1.js:47)
    at Ejercicio 1.js:75

which is on the next line of class Trabajador

this.nombreEmpresa = nombreEmpresa;

What am I doing wrong?

    
asked by Luis Gabriel Fabres 05.03.2017 в 16:28
source

1 answer

8

The class Persona has a constructor that accepts two parameters, therefore, the class expects to receive these parameters in the initialization of the class, that is, when you do new . The way to delegate these parameters to the father is by means of the reserved word super :

constructor(nombre, apellido, nombreEmpresa, direccionEmpresa) {
  super(nombre, apellido);
  this.nombreEmpresa = nombreEmpresa;
  this.direccionEmpresa = direccionEmpresa;
}

In this way, the parameters nombre and apellido are delegated to the base class and therefore, are inherited in Trabajador , so you can continue to access them by means of this.nombre and this.apellido respectively.

Keep in mind that you are using getters and setters for public properties . Currently, EcmaScript is in the process of evaluating private properties in ES2015 classes , so for now > it is not possible to have private properties in ES2015; On the other hand, you can emulate them by defining the private properties outside the class or using Symbols .

Update

  

Should you always use super when using the inheritance? - @toledano

Rpta: as long as you define a constructor in the child class.

In classes ES2015 it is mandatory to call super() in child classes if a constructor is defined in them. Take the following example:

class A {
  constructor() {
    this.prop = 'Hola';
  }
}

class B extends A {
  constructor() {
    // no funciona, se debe llamar a super()
    //super();
  }
}

alert(new B().prop);

The previous code, although the constructor does not define anything, needs to call super() for a correct instantiation of the class. If you remove the constructor of the daughter class, you will see that the instantiation occurs correctly.

  

Do you always have to delegate these properties to the mother class? - @toledano

Yes, because if you do not define a constructor in the child classes, an implicit super() will be produced during the initialization; therefore, if the base class receives parameters and the implicit call does not send them, an error will occur because there is no empty constructor.

However, it is not mandatory at all to call super() in the child classes. This exception occurs when the base class has default parameters in its constructor. For example:

class A {
  constructor (required = false) {
    this.required = required;
  }
}

class B extends A {}

alert(new B().required);

In the previous code you see how it is executed correctly and this is because a constructor with default parameters does not require a call with the existence of them since they are currently "predefined".

    
answered by 05.03.2017 в 16:51