Constructor Functions
Previously, we have created objects using the object literal notation. Likewise, we can even write functions that _return _objects. There is yet another way for us to create objects, and it is the foundation of object-oriented JavaScript: the constructor function. We saw a bit of it back in Lesson 1 when invoking theObject()
constructor function. Now, let's take a deeper dive into it!
To instantiate (i.e.,create) a new object, we use thenew
operator to invoke the function:
new SoftwareDeveloper();
The first thing to note above is the use of thenew
keyword. Second, note that the name of the constructor function,SoftwareDeveloper()
, is written with the first letter capitalized to _visually _distinguish it from a regular function.
Keep in mind that even though the function's name starts with a capital, that doesn't _automatically _make this a constructor function (i.e., though developers name constructor functions in CamelCase by convention, it is _not _enforced by the language). What _does _makeSoftwareDeveloper()
a constructor function are:
- The use of the
new
operator to invoke the function - How the function is coded internally (which we'll look at right now!)
Constructor Functions: Structure and Syntax
This is what the internals of a constructor function looks like:
function SoftwareDeveloper() {
this.favoriteLanguage = 'JavaScript';
}
This might seem a bit different than the functions you've written up to this point, so let's break it down!
First, rather than declaring local variables, constructor functions persist data with thethis
keyword. The above function will add afavoriteLanguage
property to any object that it creates, and assigns it a default value of'JavaScript'
. Don't worry too much aboutthis
in a constructor function for now; just know thatthis
refers to the new object that was created by using thenew
keyword in front of the constructor function. We'll go into more detail aboutthis
soon!
One last thing that might seem unusual is that this function doesn't seem to return anything! Constructor functions in JavaScript _should not _have an explicit return value (i.e., there should _not _bereturn
statement).
Great! Now that we've seen the structure and syntax of a constructor, how can we use it to create an object?
Creating a New Object
As we've seen above, let's use thenew
operator to create a new object:
let developer = new SoftwareDeveloper();
We've saved the return value of this invocation to the variabledeveloper
. Let's executeconsole.log(developer);
to log thisSoftwareDeveloper
object to the console:
TheSoftwareDeveloper
object is logged to the console.
Here's the code from the preceding video.
Creating Multiple Objects
What's more: we can even use the _same _constructor function to create as many objects as we'd like!
Let's invoke the sameSoftwareDeveloper()
constructor two more times to instantiate two additional objects:engineer
andprogrammer
.
let engineer = new SoftwareDeveloper();
let programmer = new SoftwareDeveloper();
console.log(engineer);
// SoftwareDeveloper { favoriteLanguage: 'JavaScript' }
console.log(programmer);
// SoftwareDeveloper { favoriteLanguage: 'JavaScript' }
Constructor Functions Can Have Parameters
Just like regular functions, one benefit of using constructor functions is that they can also accept arguments. Let's update the constructor above to accept a single argument, and assign thename
property to it:
function SoftwareDeveloper(name) {
this.favoriteLanguage = 'JavaScript';
this.name = name;
}
In the updatedSoftwareDeveloper()
function, whatever value is passed into the function will be the value of the object'sname
property. Let's check it out:
let instructor = new SoftwareDeveloper('Andrew');
console.log(instructor);
// SoftwareDeveloper { favoriteLanguage: 'JavaScript', name: 'Andrew' }
Great! And as we've seen above, we can create different objects using the same constructor. Let's call the same constructor function but pass a different argument this time:
let teacher = new SoftwareDeveloper('Richard');
console.log(teacher);
// SoftwareDeveloper { favoriteLanguage: 'JavaScript', name: 'Richard' }
Just to recap: above, we passed the string'Richard'
into theSoftwareDeveloper()
constructor function, then instantiated a new object.'Richard'
then became the value of thename
property in theteacher
object.
Let's check out another example!
Here's the code from the preceding video.
QUESTION 1 OF 4
Which of the following about constructor functions are true? Constructor functions (select all that apply)...
should have areturn
statementmust be invoked with
new
are used to instantiate a new object
can have at most two parameters/arguments
SUBMIT: A constructor function doesn't directly return anything (i.e., there's no explicit return
statement), but invoking them with the new
operator constructs a new object.
QUESTION 2 OF 4
What happens if a constructor function begins with a lower-case letter?
A new object isn't created.An error occurs.this
cannot be used inside a function.Nothing. It will still work.
SUBMIT: Capitalizing the first letter of a constructor function's name is just a naming convention. Though the first letter
_should _be capitalized, inadvertently leaving it lower-cased still makes the constructor function (i.e., when invoked with the
new
operator, etc.).
/*
Now it's your turn to create a constructor function. Declare a
`Sandwich` constructor function that takes three parameters:
1. `bread` (string) - the type of bread for the sandwich (e.g. "Wheat")
2. `meat` (array) - the meats to put on the sandwich
(e.g. `[]` for a vegetarian sandwich!)
3. `vegetables` (array) - the vegetables to include in the sandwich
*/
function Sandwich (bread, meat, vegetables) {
this.bread = bread;
this.meat = meat;
this.vegetables = vegetables;
console.log(`I would like a ${this.meat} sandwich on ${this.bread} with ${this.vegetables}.`);
}
const order = new Sandwich('Italian white', ['grilled turkey breast', 'Swiss cheese'], ['tomatoes', 'lettuce']);
- RESET QUIZ
- TEST RUN
- SUBMIT ANSWER
⚠️ Omitting the
new
Operator ⚠️What happens if you inadvertently invoke a constructor function_without_using the
new
operator?
function SoftwareDeveloper(name) { this.favoriteLanguage = 'JavaScript'; this.name = name; } let coder = SoftwareDeveloper('David'); console.log(coder); // undefined
What's going on? Without using the
new
operator, no object was created. The function was invoked just like any other regular function. Since the function doesn't_return_anything (exceptundefined
, which all functions return by default), thecoder
variable ended up being assigned toundefined
.One more thing to note: since this function was invoked as a regular function, the value of
this
is also drastically different. Don't worry too much about this for now; we'll take a deep dive into thethis
keyword in the very next section!
Seeing the Object's Constructor (instanceof
)
What if we want to see if an object was created with a constructor function in the first place? We can use theinstanceof
(which returns a boolean) to give us some insight. Let's check it out!
Here's the code from the preceding video.
💡
instanceof
and the Prototype Chain 💡In the above example,
instanceof
confirmed that a specific constructor function did in fact create a specific object. We know this because we directly instantiated thedev
object after invoking theDeveloper()
constructor function.Many times, however, it's a bit more complex: the
instanceof
operator actually tests whether or not that constructor appears in theprototype chainof an object. This means that we can't always check exactly_which_constructor created that object, but it does give us insight as to what_other_properties and methods an object may have access to.For now, don't worry too much about the prototype chain or any of these additional properties or methods; we'll take a very close look at them soon!
QUESTION 4 OF 4
Consider the following constructors:
function Finch(name) {
this.kingdom = 'Animalia';
this.name = name;
}
function Sparrow(name) {
this.kingdom = 'Animalia';
this.name = name;
}
Let's create an instance of each constructor:
const atticus = new Finch('Atticus');
const jack = new Sparrow('Jack');
What is the result whenatticus instanceof Sparrow;
is executed?
true
false
undefined
null
The console throws an error
SUBMIT: false
is returned. Not only is Sparrow
not the atticus
object's constructor function -- the Sparrow
object is nowhere to be found in atticus
's prototype chain.
Summary
JavaScript's class system is built directly on using functions and objects. Calling (i.e., invoking) a constructor function with thenew
operator instantiates a new object. The same constructor function can be used to create different objects.
We've discussed functions, objects, andthis
throughout this course. As it turns out, all three are very much interconnected with one another! We'll examine their relationship in the next section as we take an in-depth look at thethis
keyword.
Further Research
- The new operator on MDN
- The instanceof operator on MDN