// This function is called via 'new', so 'this'
// will be set to a new empty object
function Person(name, age, preferredFood)
{
// Add the parameters as properties on the new object
this.name = name;
this.age = age;
this.preferredFood = preferredFood;
}
// Now each person object can be created with 'new'
let person1 = new Person("Joe", 25, "pizza");
let person2 = new Person("Jenny", 30, "noodles");
let person3 = new Person("Maya", 20, "burrito");
// Show each person in the console
console.log("person1:", person1);
console.log("person2:", person2);
console.log("person3:", person3);
This eliminates the repetition, makes it much easier to change the properties used by the Person object (as they are all specified in one place now), and allows creating more complex objects with a much smaller amount of code. This is a key aspect of object-oriented programming, as now we can conveniently create specific types of objects to represent specific types of things.
JavaScript is pretty relaxed about the use of functions and new
. It's possible to call the Person
function like a normal function without new
. Similarly you could call any other function with new
even if it wasn't intended for it. However neither case is actually particularly useful. So it's best to only use new
with a dedicated function intended for use with it.
Functions used with new
are referred to as constructor functions, because they construct (i.e. create) a new object in a certain way. (There's no pun intended with the name of the software Construct that we've been using!)
Methods
It's also possible to add methods in a constructor function, like so:
function Person(name, age, preferredFood)
{
this.name = name;
this.age = age;
this.preferredFood = preferredFood;
// Add a function
this.logName = function ()
{
console.log(`The person's name is ${this.name}`);
}
}
// Create a person
let person = new Person("Joe", 25, "pizza");
// Call the logName function on it
// Logs: The person's name is Joe
person.logName();
Note that since the method is called with person.logName()
, then inside the logName
function this
refers to person
, and so it works as expected.
However this approach to adding methods is not actually widely used in practice. The problem is it creates a separate copy of the logName
function for every single Person
that is created. This is necessary for the data properties, but not necessary for functions - it's more efficient to share the same single logName
function across all Person
objects.
This can be achieved by assigning functions to Person.prototype
, which involves JavaScript's prototype chain, a fairly advanced topic. However with modern JavaScript this approach has also been superseded by classes. Since most code is now written this way and it solves the same problem, we will skip over the details of prototype chains and move straight on to classes.