- After this lesson, students will be able to:
- Use constructor functions to create objects
- Explain how
new
relates to constructor functions - Describe the need for constructor functions in OOP
- Explain how
this
is used in constructor functions - Explain the difference between the returned values of regular functions and constructor functions
- Constructor functions are useful in OOP (Object Oriented Programming) because they allow us to create multiple objects with specific properties and methods which we define.
- Just like all arrays can access a set of methods defined in JavaScript, objects built using constructor functions we write can all access the methods which we define for that constructor.
- We've already talked about how to make objects. Let's review a couple of ways to make them before we get to constructors.
Creating objects using object literals:
var freddie = {
name: 'Freddie',
hairColor: 'black'
}
var mercury = {
name: 'Mercury',
hairColor: 'orange'
}
var delilah = {
name: 'Delilah',
hairColor: 'grey'
}
// Creating objects using functions that return an object:
function cat(name, hairColor) {
return {
name: name,
hairColor: hairColor
}
}
var freddie = cat('Freddie','black')
/* { name: 'Freddie', hairColor: 'black' } */
var delilah = cat('Delilah','grey')
// => { name: 'Delilah', hairColor: 'grey' }
- Sometimes you will want several objects to represent similar things.
- Object constructors can use a function as a template for creating objects.
Why might OOP be helpful in your first project?
- The
new
keyword and the object constructor create a blank object. You can then add properties and methods to the object. - Create an object using Object literal or Object constructor:
var obj = {}
// or
var obj = new Object()
// both are the same!
- Just like with the JavaScript constructor
Object
, we can use thenew
keyword to create instances of our own constructor function.
function Cat() {
}
var delilah = new Cat()
- The
this
keyword is used instead of the object name to indicate that the property or method belongs to the object thatthis
function creates.
function cat(name, hairColor) {
var model = {}
model.name = name
model.hairColor = hairColor
return model
}
var mercury = cat('Mercury','orange')
- Use the
this
keyword in a Constructor function:
function Cat(name, hairColor) {
this.name = name
this.hairColor = hairColor
}
var freddie = new Cat('Freddie','black')
- Create a constructor function for a car. It should have the following properties: make, model, and year.
- Use the
Car
constructor function to create two cars.
- Inheritance is when an object is based on another object, using the same implementation to maintain the same behavior.
- Prototypes in Javascript can be used to add methods to all objects created by a specific constructor function, or to specify another constructor function from which this one inherits methods.
- What is a prototype?
// A first, typical or preliminary model of something, especially a machine, from which other forms are developed or copied
- You have already been using inheritance!
String.toUpperCase()
,Array.splice()
, etc. - Those methods are inherited from the String and Array constructors built into the core of JavaScript, and they are available on all instances of strings and arrays which you create.
You can use prototype
to add methods onto all of the objects that are created using a constructor function.
var Machine = function(name, purpose) {
this.name = name
this.purpose = purpose
}
Machine.prototype.purchase = function() {
return 'You purchased a(n) ' + this.name + '.'
}
var computer = new Machine('MacBook Pro', 'code and internet and stuff')
var tablet = new Machine('iPad', 'internet and games and stuff')
computer.purchase() => 'You purchased a(n) MacBook Pro.'
tablet.purchase() => 'You purchased a(n) iPad.'
You can also use prototype
to make a new constructor which inherits methods from another constructor.
Phone.prototype = new Machine()
Phone.prototype.constructor = Phone
function Phone(brand, name) {
this.brand = brand
this.name = name
this.purpose = 'to make calls, maybe?'
}
var iPhone = new Phone('Apple', 'iPhone')
var android = new Phone('Samsung', 'Galaxy S 7')
iPhone.purchase() => 'You purchased a(n) iPhone.'
android.purchase() => 'You purchased a(n) Galaxy S 7.'
Notice that purchase
was not specifically written for Phone
, but it is available to Phone
because Phone
inherits it from Machine
.
- One way to define a class is using a class declaration. To declare a class, you use the class keyword with the name of the class.
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
- A class expression is another way to define a class. Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body.
// unnamed
var Polygon = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
// named
var Polygon = class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
get area() {
return this.calcArea();
}
calcArea() {
return this.height * this.width;
}
}
var square = new Polygon(10, 10);
console.log(square.area);
- The static keyword defines a static method for a class.
- Static methods are called without instantiating their class and are also not callable when the class is instantiated.
- Static methods are often used to create utility functions for an application.
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy);
}
}
var p1 = new Point(5, 5);
var p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));
- The extends keyword is used in class declarations or class expressions to create a class as a child of another class.
- We will see a similar pattern for inheritance in ruby and other languages
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
d.speak();
- If there is a constructor present in sub-class, it needs to first call super() before using "this".
- One may also extend traditional function-based "classes":
class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
- In 5 minutes, Using your
Car
constructor, do the following:
- Add a method to its prototype called
go
.- This function should accept a number.
- If the number is at least 90, return 'Pedal to the metal!'
- If the number is less than 90, return 'Speed up, granny!!'
Car.prototype.go = function(speed) {
if(speed >= 90) {
return "Pedal to the metal!"
} else {
return "Speed up, granny!"
}
}
- Add another method to its prototype called
getDetails
.- This function should return the make, model and year of the car
- Bonus: write a constructor for
Volkswagen
(or any make you choose) which inherits fromCar
. Make one Volkswagen using the constructor function. Check to make surego
andgetDetails
work on new instances ofVolkswagen
.
- Explain the
new
key word. - How is
this
used in constructor functions? - Why are constructor functions useful in OOP?
- What is the
prototype
property?