Ir al contenido
wannacode

Constructores y this

En resumen: El constructor en JavaScript es el método constructor, que se ejecuta con new y rellena los campos del objeto a través de this.

Problema

Un café de NaN €

Creas un producto, igual que en la lección anterior, y rellenas los campos línea por línea. Se te olvidó una línea:

const coffee = new Product();
coffee.name = "Café";
coffee.quantity = 2;
console.log(`${coffee.name}: ${coffee.price * coffee.quantity} €`);
Salida
Café: NaN €

El café cuesta NaN € (Not a Number, «no es un número»): el precio es undefined, y undefined * 2 no es un número. JavaScript no se queja. Cuantos más campos tiene una clase, más fácil es saltarse uno. Y un producto sin precio ni siquiera debería poder existir.

La idea

Constructor: sin estos datos no hay objeto

Una clase puede decir qué necesita antes de que puedas crear un objeto a partir de ella. Para eso sirve el constructor: un método especial que se ejecuta con new.

shop.js
class Product {
name;
price;
quantity;
constructor(name, price, quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
const coffee = new Product("Café", 7.50, 2);
console.log(`${coffee.name}: ${coffee.price * coffee.quantity} €`);
Salida
Café: 15 €
  • El constructor se llama constructor, en todas las clases.
  • Sus parámetros son los datos sin los que un producto no puede existir. Los pasas en los paréntesis de new: new Product("Café", 7.50, 2).
  • No devuelve nada. new devuelve el objeto nuevo.

Ahora el precio se fija en la misma línea que crea el producto, y se ve cuando falta. Pero JavaScript no cuenta los argumentos. Si pasas dos en lugar de tres, el programa se ejecuta, y la cantidad es undefined:

const coffee = new Product("Café", 7.50);
Salida
undefined
Café: NaN €

Así que el número de argumentos lo tienes que revisar tú. Cómo un constructor puede rechazar un objeto incorrecto lo verás en el módulo «Errores y excepciones».

constructor(name, price, quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
const coffee = new Product("Café", 7.50, 2);
console.log(`${coffee.name}: ${coffee.price * coffee.quantity} €`);
Paso a paso, en palabras
  1. new reserva un objeto nuevo. Sus campos todavía son undefined.
  2. Se ejecuta el constructor. Los argumentos se copian en sus parámetros.
  3. this.name = name: del parámetro al campo de este objeto.
  4. Lo mismo para el precio y la cantidad.
  5. El constructor termina y los parámetros desaparecen. coffee recibe una flecha al objeto terminado.
  6. El objeto sale de new ya rellenado, así que el precio no es undefined.

La idea

this: el campo de este objeto

Dentro del constructor hay dos cosas que se llaman name: el parámetro y el campo. El nombre solo es el parámetro. Para el campo escribes this.name.

constructor(name, price, quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}

this es el objeto que se está creando ahora mismo. this.name = name; significa «guarda el parámetro name en el campo name de este objeto».

En JavaScript, this. es obligatorio siempre que tocas un campo. Sin él, name es siempre el parámetro (u otra variable), nunca el campo.

Pruébalo

Encuentra el error

El programa debería imprimir «Té: 3.2 €». En cambio, imprime «undefined: 3.2 €». ¿Qué línea tiene el error?

Elige la línea con el error.

La idea

¿Y el new Product() de la lección anterior?

En la lección anterior no había constructor, y new Product() funcionaba: si no escribes un constructor, JavaScript añade uno vacío. En cuanto escribes el tuyo, cada new lo llama.

Pero JavaScript no revisa si se pasan todos los argumentos. new Product() sigue funcionando, y los campos se quedan en undefined:

const empty = new Product();
Salida
Product { name: undefined, price: undefined, quantity: undefined }

console.log de un objeto muestra sus campos. Aquí se ve que ninguno está rellenado. En Java y C# una línea así no compila, pero en JavaScript depende de ti: pasa todos los argumentos.

La idea

Una cantidad por defecto

La mayoría de los productos del carrito van de uno en uno. Escribir 1 cada vez cansa.

En JavaScript una clase puede tener un solo constructor. En lugar de un segundo constructor, el parámetro recibe un valor por defecto: si no pasas una cantidad, es 1.

constructor(name, price, quantity = 1) {
this.name = name;
this.price = price;
this.quantity = quantity;
}

quantity = 1 significa «si no se pasa una cantidad, usa 1». Pon un parámetro así al final: así puedes simplemente omitirlo al llamar.

Más precisamente, para curiosos

Un segundo constructor en la clase es un error, y el programa ni siquiera arranca:

Error
SyntaxError: A class may only have one constructor

La ventaja de un solo constructor: si mañana añades una comprobación del precio, está en un solo lugar.

Pruébalo

¿Qué constructor?

¿Qué imprimirá el programa?

class Product {
name;
price;
quantity;
constructor(name, price, quantity = 1) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
const bread = new Product("Pan", 1.20);
const milk = new Product("Leche", 2.10, 3);
console.log(bread.quantity, milk.quantity);
Respuesta

Pruébalo

¿Cómo se llama el constructor?

¿Qué va en el hueco?

class Book {
  title;
  author;

  (title, author) {
    this.title = title;
    this.author = author;
  }
}

Ejercicio

Objetos creados completos

Resuélvelos en tu editor. Cada clase recibe un constructor con parámetros para todos sus campos.

1. Persona. Una clase Person con un nombre y una edad. Crea dos personas e imprime sus datos.

Salida
María, 34 años
Pablo, 19 años

2. Animal. Una clase Animal con una especie y una edad. Crea un gato de 3 años y un perro de 7.

Salida
Especie: gato, edad: 3
Especie: perro, edad: 7

3. Paso de baile. Una clase DanceMove con un nombre y una duración en segundos. En la lección «Métodos de instancia», el paso aprenderá a «ejecutarse» solo.

Salida
moonwalk: 5 s

Más práctica

  • Un libro con constructor. Reescribe Book de la lección anterior con un constructor constructor(title, author). ¿Cuántas líneas ahorraste en el código de debajo de la clase?
  • Un producto con cantidad por defecto. Product con quantity = 1, como en la lección. Haz un array [new Product("Pan", 1.20, 2), new Product("Café", 7.50)] e imprime el nombre y la cantidad de cada uno: «Pan x2», «Café x1».
  • Reserva. Una clase Booking con el nombre del huésped, el número de noches y el precio por noche. Imprime cuánto cuesta la estancia: 3 noches a 85 € son 255 €.

Test

Ponte a prueba

1. ¿Cuándo se ejecuta el constructor?
2. ¿Cómo se llama el constructor en JavaScript?
3. El constructor es constructor(name, price). ¿Qué pasa con new Product()?
4. El constructor dice this.name = name; ¿Qué es this.name?
5. ¿Cómo da la clase una cantidad de 1 cuando no se pasa ninguna al crear el objeto?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·