Introduction:
This is by no means an exhaustive guide to Object Oriented Programming in Javascript. These notes on OOP in JavaScript are what I mostly use, and come back to them daily for reference.
On this note, I primarily focus on creating objects with class
and function
keywords. I also talk about inheritance
method chaining and some other stuff. For a detailed explanation and examples, please visit the MDN's blog here on classes.
Object Oriented Programming TLDR
Object Example
An Object in JavaScript is a collection of properties. Property can be functions (function has an action associated with it) or a simple
key
:value
pair which could just represent a feature of the object it is in. For example:color: red
is a property whereasfunction accelerate(){}
is a property of the car that has some action associated with it.- For example,
const car = {
color: red,
type: sedan,
accelerate: function(){
// code here
}
}
Please Note: I have assigned the object above to a variable called car. If you don't need to refer back to the object, you don't need to assign the object to a variable.
Creating Objects: Object Literal
- Also known as object initializers, object literals allow us to create Javascript objects. We need to use curly braces in JavaScript to initialize the object.
// empty object
let obj = {}
// object with property and value
let user = {
name: 'John Doe', // property can be identifies
1000: 'example_1', // or property can be a number
"email": 'john.doe@useremail.com', // or it can be a string.
login: function(){}
logout(){} // ES6 syntax.
}
- In the
user
the object above, we have encapsulated or gathered all the relevant properties of a user in one place. Think of opening and closing curly braces{}
as a capsule that groups all the relevant properties of user.
Accessing and Updating Properties
Accessing Object Properties
- To access object properties we can use simple dot notation.
console.log(user.email)
// expected output: john.doe@useremail.com
- However, dot notation only works when the object has an identifier that starts with a
letter
,$,
_
orunicode
escape sequence. So, to access the property of type number you need to use the following syntax.
console.log(user[1000]) // expected output: example_1
// this notation below works for other properties as well.
console.log(user['email']) // expected output: john.doe@useremail.com
- We can access the properties of objects dynamically as well.
let foo = 'email'
console.log(user[foo]) // expected output: john.doe@useremail.com
// changing the variable
let foo = 'name'
console.log(user[foo]) // expected output: John Doe
Updating Object Properties
- To update the property, simply
get
the property name andset
it to new value. For example, for our user object, we can do the following.
user[1000] = "example_2";
user.email = "email@johndoe.com";
- Setting a property that does not exist on the object:
user.race = 'South Asian'
console.log(user) // expected output contains: {.... race: "South Asian"}
Class and Constructor Function: Creating Multiple Objects With the Same Property
You might have to create multiple objects with the same property types, just like creating multiple computers or cars with the same features (property).
First, create a constructor class (blueprint) of the object.
class Car {
constructor(color, type, accelerateFn){
this.color = color;
this.type = type;
this.accelerate = function(){console.log(accelerateFn)};
}
}
this
represents the object it is in. When we create a new object (example:whiteCar
) with the blueprint above,this
keyword will represent the object just created (whiteCar)
- Also, there can only be one method with the name
constructor
inside the Class.
Now to create a new object with all these properties of the constructor class, do the following.
const whiteCar = new Car('white','hatchback','is a fast car')
console.log(whiteCar.color) // expected output: white
const redCar = new Car('red', 'sedan', 'is slower car')
console.log(redCar.color) // expected output: red
Methods:
- For the example above: we can add methods
brake
andheadlights
like this
class Car {
constructor(color, type, accelerateFn){
this.color = color;
this.type = type;
this.accelerate = function(){console.log(accelerateFn)};
}
// methods
brake(){
console.log(`Brake of this ${this.color} ${this.type} is in good condition.`)
return this;
}
headLights(){
console.log(`Lights of this ${this.color} ${this.type} is in good condition.`)
return this;
}
}
- If you want the
methods
orproperties
to not be shared with another object/instance created from the class, use the wordstatic
class Car {
constructor(color, type, accelerateFn){
this.color = color;
this.type = type;
this.accelerate = function(){console.log(accelerateFn)};
}
// methods
brake(){
console.log(`Brake of this ${this.color} ${this.type} is in good condition.`)
return this;
}
headLights(){
console.log(`Lights of this ${this.color} ${this.type} is in good condition.`)
return this;
}
// static example:
static moto = 'Let\'s make the world a better place'
static hello(){
console.log(`This method is only available in this Car Object`)
}
}
Method Chaining.
return this
in the above object, methods return the object it is in. What that allows us to do is call all the methods of the object after one another.
For example,
const redCar = new Car('red','sedan','is faster')
console.log(redCar.brake().headLights())
Here, we can call headlights()
after brake()
.
Class Inheritance
- If you want to create a new object with all the properties of the previous one plus some more properties and methods of its own, you need to inherit the properties of the previous object with class Inheritance.
class SuperCar extends Car {
launchMode(){
console.log(`Launch Mode of ${this.color} supercar`)
}
}
- Now when you create a new
SuperCar
, you need to do this
const ferrari = new SuperCar('red','super-car','is fastest')
Note: The new object that extends on properties of another object expects all the arguments of the previous one. Therefore, in this example above, we need to provide in
color
,type
andaccelerateFn
Emulating Class with function
Keyword
- The following code with
function
keyword is also valid
function Car(color, type, accelerateFn){
this.color = color;
this.type = type;
this.accelerate = function(){console.log(accelerateFn)};
}
// to attach methods, we can use prototype
Car.prototype.brake = function(){
console.log(/*code here*/)
}
Now, an instance of the object can just call in the method
const ferrari = new SuperCar('red','super-car','is fastest')
ferrari.brake(); // works. :)
Inheritance of class created with the function keyword
- To create a new Object from the original object (with constructor function) created with
function()
keyword, do this.
function SuperCar(...args) {
Car.apply(this, arg)
}
// here, ...args is taking arguments of Car and making them an array.
Now, you can create an object like this
new lambo = new SuperCar('red','superCar','is fastest') // with all the same args
- To inherit the prototype methods attached to the original object created with
function()
keyword, useObject.create()
like so.
SuperCar.prototype = Object.create(Car.prototype) // now all the prototype functions appear for SuperCar object as well.
Important Note:
- An Important difference between
funciton decleration
andclass decleration
is that while functions can be called before they are defined but classes can't.
const ferrari = new SuperCar()
class SuperCar = {}
// Refrence Error because we are calling function before creating it.