Today, we are going to be making a person (not in that sense, you) using a constructor function. When this function get’s called using the new keyword, it will construct and return an object, that’s why we call it constructor. I could go on and on about objects, but that’s not the aim of this post, so I’ll keep it short and example oriented; here’s an example of a simple constructor using a function expression, it creates cats:
var Cat = function(name, age) { this.name = name; this.age = age; this.greet = function() { console.log('Meow! -said ' + this.name); } } var fluffy = new Cat('Fluffy', 2); console.log(fluffy.name); //-> Fluffy console.log(fluffy.age); //-> 2 fluffy.greet(); //-> Meow! -said Fluffy
As you can see, calling the Cat constructor using the new keyword, created a new cat named Fluffy (an object). This object has three properties that we can access: name, age and greet. Greet is actually a function, so we will refer to it as a method, and will access it using this notation: fluffy.greet().
Let’s see what we actually need to accomplish for the Make a Person bonfire before we go any further. We must create an object constructor with the following methods:
- getFirstName() – Return the first name.
- getLastName() – Returns the last name.
- getFullName() – Return the full name.
- setFirstName(first) – Sets the first name to the given string.
- setLastName(last) – Sets the last name to the given string.
- setFullName(firstAndLast) – Sets the full name to the given string.
Not only do we need to implement each of these methods (properties that contain a function), but we also need to make sure that these are the only means of accessing the information inside the Person object. How do we do that? The cat example clearly did not accomplish this, since we could easily access both name and age! Let’s see how to create private properties in an object changing the previous Cat example:
var Cat = function(name, age) { var name = name; // We dont use the this keyword here anymore. var age = age; this.getName = function() { // We create a getter method that returns the info that we need. return name; } this.getAge = function() { return age; } this.greet = function() { console.log('Meow! -said ' + name); } } var snowball = new Cat('Snowball', 5); console.log(snowball.name); //-> undefined console.log(snowball.age); //-> undefined console.log(snowball.getName()); //-> Snowball console.log(snowball.getAge()); //-> 5 fluffy.greet(); //-> Meow! -said Snowball
Great! Now we have read access to the information that we want, does it not seem similar to getting the first, last and full name of the Person object? Let’s turn our Cat into a Person!
var Person = function(firstAndLast) { var fullName = firstAndLast; // We set the full name. firstAndLast = firstAndLast.split(' '); // Split the input name into first and last names; var firstName = firstAndLast[0], // First name. lastName = firstAndLast[1]; // Last name. this.getFirstName = function() { return firstName; }; this.getLastName = function() { return lastName; }; this.getFullName = function() { return fullName; }; // Set methods will go here! }
Great! We now have a Person constructor that will let us get the values that we want, but we do not have a way of changing those values, let’s try it:
var jack = new Person('Jack Power'); console.log(jack.getFirstName()); //-> Jack console.log(jack.firstName); //-> undefined jack.firstName = 'Joe'; console.log(jack.getFirstName()); //-> Still Jack!
To be able to edit these fields, we need to define the methods that will set them (we call them setter methods, funnily enough). Let’s create a setter method for the first, last and full name of the person object, they each will take an argument (first, last or full name):
var Person = function(firstAndLast) { var fullName = firstAndLast; firstAndLast = firstAndLast.split(' '); var firstName = firstAndLast[0], lastName = firstAndLast[1]; this.getFirstName = function() { return firstName; }; this.getLastName = function() { return lastName; }; this.getFullName = function() { return fullName; }; this.setFirstName = function(first) { firstName = first; }; this.setLastName = function(last) { lastName = last; }; this.setFullName = function(firstAndLast) { fullName = firstAndLast; }; }
This constructor will pass every test thrown by Free Code Camp, but if we look closely, there are a few issues with it. If we set the full name, would it not make sense for the first and last name to also me updated? Not only that, but why keep the fullName variable inside the constructor, when we can easily concatenate the first and the last to get it?
Let’s create some logic so that we get this issues fixed:
var Person = function(firstAndLast) { var firstName, lastName; // Initialize both variables. this.getFirstName = function() { return firstName; }; this.getLastName = function() { return lastName; }; this.getFullName = function() { return firstName + ' ' + lastName; // Concatenate the first and last name to get the full name. }; this.setFirstName = function(first) { firstName = first; }; this.setLastName = function(last) { lastName = last; }; this.setFullName = function(firstAndLast) { // We place this logic in the setFullName method firstAndLast = firstAndLast.split(' '); firstName = firstAndLast[0]; lastName = firstAndLast[1]; }; this.setFullName(firstAndLast); // We call the setFullName method as soon as a person is created. }
Now we are making sure that no matter what we change, this person will always return coherent information. Remember, if something isn’t clear to you, shoot me an email, post a comment or hit me up on Twitter, I’ll gladly help you out!