Lesson 3 - Object Properties and Constructors in JavaScript
In the previous lesson, The First Object-Oriented Application in JavaScript, we wrote our first object application. We
can already declare classes and their methods representing actions they can
perform. We can then create a new instance based on a class using the
new
keyword. We also know that we can define properties in classes,
which we haven't tried yet. We're going to focus on the object properties in
today's object-oriented JavaScript programming tutorial.
Properties
Let's create a new sample program, this time we'll represent companies.
First, we'll consider which properties our company should have. We can assign
a name, address, and employee list to it. We'll create a Company.js
file and leave it as an empty class for now:
class Company { }
We'll work with classes in a separate file again, it may be called
app.js
as before. There we can create a new instance of our
company:
const microsoft = new Company();
Be sure to load the Company.js
file in index.html
.
We'll show other ways to import files further in the course.
Class properties are basically variables that the instances of that class will have. We can access them from within the class without having to pass them as parameters. And we can access them from the outside too, on a specific instance created.
Let's define a name
property to our microsoft
instance. We access instance properties through the dot .
operator,
which means that what we're writing belongs to the instance. Next, we'll write
the property name. The syntax may look like this:
microsoft.name = "Microsoft Corporation";
Let's add this line to app.js
and try to print our property on
the page. Now the complete app.js
could look like this:
const microsoft = new Company(); microsoft.name = "Microsoft Corporation"; // Add a name property with a value to our company document.write(microsoft.name); // Print it on the page
Now, let's open the page in our browser:
As we see, the property of our instance has been printed. This is how we can continue to create multiple company instances with different names:
const microsoft = new Company(); microsoft.name = "Microsoft Corporation"; const google = new Company(); google.name = "Google LLC"; document.write(microsoft.name); // Print company names document.write('<br />'); document.write(google.name);
The result:
The Constructor
Since our class is now empty, we'd have to add the name
property
like this to all other further Company
class instances so they all
have it. If we ignore the fact that it's a lot of repetitive code, if there were
more properties or instances, we could forget about some easily. That's not very
practical. Therefore, we can use a special class method, the constructor, to add
instance properties.
The constructor is a method that is called automatically when a new
instance of the class is being created. It is, of course, used to set
the internal state of the object and to initialize it if necessary. It's in the
constructor where we can create properties for new instances easily. Let's try
it on our Company
example.
The Company Constructor
In the class, we'll need to access its current instance that is being
created, and set it appropriate properties. We access the current instance of
the class using the this
keyword, which unfortunately behaves
differently in JavaScript, depending on the context. We'll return to this issue
several times in this course.
So we'll add a constructor to the class in the Company.js
file,
which is the method called when new instances are being created. We'll set all
the company properties we discussed in the introduction to the current instance
in the constructor, using this
. The constructor is always named
constructor()
in JavaScript:
class Company { constructor() { this.name = "Company name"; this.address = "New York City"; this.employees = []; } }
The name and address are clear, we store them as two properties of the
string
type. All companies will now have the name
Company Name
and the address New York City
. We'll
store the employees of the company in an array, so when creating the instance,
we prepare an empty array for them.
We'll now remove the lines adding properties to the companies in
app.js
:
const microsoft = new Company(); const google = new Company(); document.write(microsoft.name); // Print company names document.write('<br />'); document.write(google.name);
Every call of new Company()
will call the constructor
automatically. When we run the script, we get a similar output as last time:
Constructor Parameters
Of course, we don't want all companies to have the same values. Therefore,
we'll pass the name and address to the company constructor as parameters. So
we'll edit Company.js
:
class Company { constructor(name, address) { this.name = name; this.address = address; this.employees = []; } }
We'll fill in the parameters when creating the class instances in
app.js
:
const microsoft = new Company("Microsoft Corporation", "Redmont, Washington"); const google = new Company("Google LLC", "Mountain View, California"); document.write(microsoft.name); // Print company names document.write('<br />'); document.write(google.name);
Now we know what the parentheses after the class name are for when creating a new instance We'll get the original output when running the script now:
Of course, we can pass parameters to any method like this, as we did in the past with functions.
Methods
As an exercise, let's add a few standard methods to the company in addition to the constructor.
Printing the Name and Address
We'll create a method for printing the name and address of our company. We'll
try that we can access instance properties from within the class easily. The
printing method in the Company
class, in the
Company.js
file, may look like this:
printCompanyInfo() { document.write(this.name + " is located in " + this.address); }
When we call it in app.js
like this:
const microsoft = new Company("Microsoft Corporation", "Redmont, Washington"); microsoft.printCompanyInfo(); // Print on the page
Our page should look like this:
It looks like everything works very well
But let's go back to our method for a while. Our way of concatenating the
text is a bit unfortunate. We always have to end the string and then append
another. This can be a source of errors and of course there's a simpler syntax
available. We can insert some values directly into a string without terminating
it in any way. We just need to use the backticks `
to declare the
string. We then insert individual variables into the string using the dollar
character and braces as ${nameOfTheValue}
.
The more elegant version of our method could look like this:
printCompanyInfo() { document.write(`${this.name} is located in ${this.address}`); }
When we run the script, we'll see the same output again. However, this syntax is much easier and clearer.
Printing Employees
Next, we'll add methods for creating employees and listing them.
As we're about to work with employees, we'll create a new class for them in
the Employee.js
file, with the constructor:
class Employee { constructor(name, age, position) { this.name = name; this.age = age; this.position = position; } }
Remember to import the class file again in index.html
:
<script src="js/Employee.js"></script>
Creating Employees
To create employees we'll get input from the user. Since we're new to
objects, we'll avoid any user interface for now and use the
prompt()
function to get the inputs. The new Company
class method looks like this:
addEmployee() { const name = prompt("Enter the employee's name"); const age = prompt("Enter the age"); const position = prompt("Enter the job position"); const employee = new Employee(name, age, position); this.employees.push(employee); // Add new employee to the array }
On the first three lines we retrieve the new employee's name, age, and job
position from the user. We then create the employee and store it in the
employee
variable. We add it to the array using the
push()
method. We'll call our new method in
app.js
:
const microsoft = new Company("Microsoft Corporation", "Redmont, Washington"); microsoft.printCompanyInfo(); microsoft.addEmployee();
New employees are not printed anywhere yet, let's fix it.
Listing Employees
In Company.js
, we'll add the last printEmployees()
method, which will print an HTML list of our employees on the page. It can look
like this:
printEmployees() { document.write("<h3>Employees</h3>"); const list = document.createElement("ul"); // Create the list as an HTML element for (const employee of this.employees) { // Fill it with data list.innerHTML += `<li><strong>Name</strong>: ${employee.name}</li>`; list.innerHTML += `<li><strong>Age</strong>: ${employee.age}</li>`; list.innerHTML += `<li><strong>Position</strong>: ${employee.position}</li><br>`; } document.body.appendChild(list); // Append the element to the page body }
We create a list
constant and a new <ul>
element in it, that is, an unordered list. Then we iterate through our array
using the foreach loop and add each employee's properties as items to the list.
Finally, we append our list into <body>
.
Now we just need to call the method in app.js
. We may want to
call the method adding an employee one more time to create another one and see
how the list looks like for more employees:
const microsoft = new Company("Microsoft Corporation", "Redmont, Washington"); microsoft.printCompanyInfo(); microsoft.addEmployee(); microsoft.addEmployee(); microsoft.printEmployees();
When we run it and fill in the data, our page might look like this:
That would be all for today. If anything goes wrong for you, there is a link
to download the complete project below to help you find your bug In the next lesson, Reference And Value Data Types In JavaScript, we'll
talk about differences between reference data types (objects) and value types
(e.g. a number
).