Constructors and this
Problem
A €NaN coffee
You create a product, just like in the last lesson, and fill in the fields line by line. You forgot one line:
const coffee = new Product();coffee.name = "Coffee";coffee.quantity = 2;console.log(`${coffee.name}: €${coffee.price * coffee.quantity}`);Coffee: €NaNThe coffee costs €NaN (Not a Number): the price is undefined, and undefined * 2 is not a number. JavaScript does not complain. The more fields a class has, the easier it is to miss one. And a product without a price should not be able to exist at all.
The idea
Constructor: no object without this data
A class can say what it needs before you can create an object from it. That is what the constructor is for: a special method that runs on new.
class Product { name; price; quantity;
constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity; }}
const coffee = new Product("Coffee", 7.50, 2);console.log(`${coffee.name}: €${coffee.price * coffee.quantity}`);Coffee: €15- The constructor is called
constructor, in every class. - Its parameters are the data a product cannot do without. You pass them in the parentheses of
new:new Product("Coffee", 7.50, 2). - It returns nothing.
newreturns the new object.
Now the price is set on the same line that creates the product, and you can see when it is missing. But JavaScript does not count arguments. If you pass two instead of three, the program runs, and the quantity is undefined:
const coffee = new Product("Coffee", 7.50);undefinedCoffee: €NaNSo you have to check the number of arguments yourself. You will see how a constructor can refuse a bad object in the "Errors and exceptions" module.
constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity;}
const coffee = new Product("Coffee", 7.50, 2);console.log(`${coffee.name}: €${coffee.price * coffee.quantity}`);Step by step, in words
- new sets aside a new object. Its fields are still undefined.
- The constructor runs. The arguments are copied into its parameters.
- this.name = name: from the parameter into the field of this object.
- The same for the price and the quantity.
- The constructor is done and the parameters disappear. coffee gets an arrow to the finished object.
- The object comes out of new already filled in, so the price is not undefined.
The idea
this: the field of this object
Inside the constructor there are two things called name: the parameter and the field. The bare name is the parameter. For the field, you write this.name.
constructor(name, price, quantity) { this.name = name; this.price = price; this.quantity = quantity;}this is the object being created right now. this.name = name; means "store the name parameter in the name field of this object".
In JavaScript, this. is required whenever you touch a field. Without it, name is always the parameter (or some other variable), never the field.
Try it
Find the bug
Pick the line with the bug.
name = name; stores the parameter in itself. The field stays undefined. You need this.name = name;. JavaScript gives no error, so a bug like this is hard to catch.
The idea
What about new Product() from the last lesson?
In the last lesson there was no constructor, and new Product() worked: if you do not write a constructor, JavaScript adds an empty one. As soon as you write your own, every new calls it.
But JavaScript does not check whether all the arguments are passed. new Product() still works, and the fields stay undefined:
const empty = new Product();Product { name: undefined, price: undefined, quantity: undefined }console.log on an object shows its fields. Here you can see that none of them is filled in. In Java and C# a line like this does not compile, but in JavaScript it is up to you: pass all the arguments.
The idea
A default quantity
Most products in the cart come one at a time. Typing 1 every time gets tedious.
In JavaScript a class can have only one constructor. Instead of a second constructor, the parameter gets a default value: if you do not pass a quantity, it is 1.
constructor(name, price, quantity = 1) { this.name = name; this.price = price; this.quantity = quantity;}quantity = 1 means "if no quantity is passed, use 1". Put a parameter like this last: then you can just leave it out when you call.
More precisely, if you are curious
A second constructor in the class is an error, and the program does not even start:
SyntaxError: A class may only have one constructorThe upside of one constructor: if you add a price check tomorrow, it is in one place.
Try it
Which constructor?
What will the program print?
class Product { name; price; quantity;
constructor(name, price, quantity = 1) { this.name = name; this.price = price; this.quantity = quantity; }}
const bread = new Product("Bread", 1.20);const milk = new Product("Milk", 2.10, 3);console.log(bread.quantity, milk.quantity);new Product("Bread", 1.20) has no quantity, so quantity takes the default value 1. For the milk, the quantity is passed: 3.Try it
What is the constructor called?
What goes in the blank?
class Book {
title;
author;
(title, author) {
this.title = title;
this.author = author;
}
}constructor: that is the constructor's name in every class.Exercise
Objects created whole
Solve these in your editor. Every class gets a constructor with parameters for all of its fields.
1. Person. A Person class with a name and an age. Create two people and print their details.
Maria, 34 yearsPeter, 19 years2. Animal. An Animal class with a species and an age. Create a 3-year-old cat and a 7-year-old dog.
Species: cat, age: 3Species: dog, age: 73. Dance move. A DanceMove class with a name and a duration in seconds. In the "Behavior" lesson, the move will learn to "perform" itself.
moonwalk: 5 sec.More practice
- A book with a constructor. Rewrite
Bookfrom the last lesson with aconstructor(title, author)constructor. How many lines did you save in the code under the class? -
A product with a default quantity.
Productwithquantity = 1, as in the lesson. Make an array[new Product("Bread", 1.20, 2), new Product("Coffee", 7.50)]and print the name and quantity of each: "Bread x2", "Coffee x1". - Booking. A
Bookingclass with the guest's name, the number of nights, and the price per night. Print what the stay costs: for 3 nights at €85, that is €255.
Test