Seleccionar página

El constructor, como su nombre indica, es el código que construye y configura un objeto cuando se crea con new. Todas las clases tienen un constructor, si no escribimos nada dentro de class se crea por defecto un constructor vacío. Si queremos escribir un constructor por nosotros mismos tenemos que incluir una función llamada constructor dentro del cuerpo de la clase.

En el caso de function es el cuerpo de la función la que hace de constructor, de hecho, se les suele llamar funciones constructoras para diferenciarlas de las funciones que no se van a utilizar con new.

classfunction
class C {
  constructor () {
  }
}

console.assert( C.prototype.constructor === C );
function C () {
}

console.assert( F.prototype.constructor === C );

El constructor se incluye automáticamente en el prototipo como propiedad constructor y se crea una anidación, ya que ese constructor a su vez tiene una propiedad prototype que a su vez tiene una propiedad constructor que apunta al inicio.

    new

    classfunction
    class C {
    }
    
    const c = new C();
    console.assert( c instanceof C );
    
    function C () {
    }
    
    const c = new C();
    console.assert( c instanceof C );
    

    Los objetos de las clases se instancian con new seguidos de una referencia a la clase, es entonces cuando se ejecuta el código del constructor.

    Una anotación, en la práctica se puede o no utilizar los paréntesis, siendo equivalente utilizar new C() que new C. Esto es sólo así cuando no se pasan parámetros al constructor, por lo que es una buena práctica mantener los paréntesis en todos los casos.

    classfunction
    class C {
    }
    
    try {
      const c = C();
      console.assert( false );
    } catch (err) {
      console.assert( err )
    }
    
    function F () {
      if (!(this instanceof F)) {
        throw new TypeError( 'Cannot call a class as a function' );
      }
    }
    
    try {
      const f = F();
      console.assert( false );
    } catch (err) {
      console.assert( err )
    }
    

    Los constructores definidos con function tiene el problema que también pueden ser llamados como funciones, es decir, sin new, algo que no ocurre con los definidos con class que lanzan una excepción si se les intenta invocar como una llamada a una función. Para tener el mismo comportamiento en la función constructora, y evitar que se puedan invocar sin new, podemos comprobar que this corresponde a una instancia de la clase y no a la propia función.

    this en el constructor

    classfunction
    class C {
      constructor () {
        console.assert( this instanceof C );
        this.a = 1;
      }
    }
    
    const c = new C;
    console.assert( c.a === 1 );
    
    function C () {
      console.assert( this instanceof C );
      this.a = 1;
    }
    
    const c = new C;
    console.assert( c.a === 1 );
    

    El valor de this en el constructor, como en todos los métodos de la clase, hace referencia al objeto que se está creando y, por lo tanto, es una instancia de la clase. Cualquier modificación que hagamos sobre el objeto this se lo estamos haciendo al nuevo objeto.

    paso de parámetros al constructor

    classfunction
    class C {
      constructor( ...args ) {
        console.assert( args[0] === 1 );
        console.assert( args[1] === 2 );
      }
    }
    
    const c = new C( 1, 2 );
    
    function C ( ...args ) {
      console.assert( args[ 0 ] === 1 );
      console.assert( args[ 1 ] === 2 );
    }
    
    const c = new C( 1, 2 );
    

    Recordemos que las clases y las funciones constructoras son ambas funciones, y como tales pueden recibir cualquier tipo de parámetros. Habitualmente contendrán información inicial relevante para la creación del objeto. No hay limitaciones o características especificas de los constructores en cuanto la paso de parámetros. En este ejemplo hemos utilizado el operador ... para recibir los parámetros. También podemos utilizar parámetros con valores por defecto y cualquier otro mecanismo de definición y recepción de parámetros.

    retorno del constructor

    classfunction
    class C {
      constructor() {
        return {a: 1, b: 2};
      }
    }
    
    const c = new C();
    console.assert( !( c instanceof C ) );
    
    function C () {
      return {a : 1, b : 2};
    }
    
    const c = new C();
    console.assert( !(c instanceof C) );
    

    Habitualmente los constructores no devuelve nada, no hace falta que lo hagan, ya está claro que queremos crear un nuevo objeto al invocarlos con new y, por lo tanto, implícitamente los constructores siempre devuelven this. Algunos programadores terminan sus constructores con return this, pero no es necesario.

    Una característica peculiar es que el constructor puede devolver un objeto diferente al que se está construyendo, por ejemplo, de otra clase o un objeto literal. Si el constructor, en vez de devolver this, devuelve otro objeto, el resultado de llamar a new será que obtenemos ese valor retornado.

    En el último ejemplo hemos devuelto un objeto literal y, por lo tanto, no es una instancia de la clase. Puede parecer un poco confuso, pero da mucha flexibilidad a la hora de configurar los objetos con los que vamos a trabajar.

    instrucciones class y function Índicepropiedades