Object Oriented Programming in JavaScript
I have been always fascinated by Object oriented programming in JavaScript. Its different from usually OOPs provided by languages such as Java.
In this post, we will look at various approaches of achieving Object oriented programming in JavaScript, and their pros and cons
Solution 1 : Generate objects using a function
function userCreator(name, score) {
const newUser = {};
newUser.name = name;
newUser.score = score;
newUser.increment = function() {
newUser.score++;
};
return newUser;
};
const user1 = userCreator("Will", 3);
const user2 = userCreator("Tim", 5);
user1.increment();
The above approach is a very naïve approach, but its absolutely useless.
- The code in the function is replicated for each of the object. If we have million users, it will have million copies of
increment
function -
If we want to add a new functionality, we will have to add it to each of the object, once it has been created.
- There is beauty of closure in above code. The function definition
increment
has reference tonewUser
but there is no reference tonewUser
once the object has been created throughuserCreator
function.
Solution 2: Using the prototype chain
function userCreator(name, score) {
const newUser = Object.create(userFunctionStore);
newUser.name = name;
newUser.score = score;
return newUser;
};
const userFunctionStore = {
increment: function() {this.score++;},
login: function() {console.log("Logged in");}
};
const user1 = userCreator("Will", 3);
const user2 = userCreator("Tim", 5);
user1.increment();
In the above solution we create a link between two objects using a hidden
property __proto__
. This property has a link to userFunctionStore
.
All objects link back to Object.prototype
Solution 3: Using the new keyboard
Using the new
keyword does the above __proto__
link automatically
All functions have a property called prototype
defined on them which points to
{}
by default.
function userCreator(name, score) {
this.name = name;
this.score = score;
}
userCreator.prototype.increment = function() { this.score++; };
userCreator.prototype.login = function() { console.log("login");};
const user1 = new userCreator("Eva", 9);
user1.increment();
In the above code, the new
keyword automates lot of things for us:
-
It links the
__proto__
property of the returned object to theprototype
property ofuserCreator
function object. -
returns
this
and stores in the global variableuser1
Solution 4 - Using the class syntactic sugar
class UserCreator {
constructor(name, score) {
this.name = name;
this.score = score;
}
increment() { this.score++; }
login() { console.log("login"); }
}
const user1 = new UserCreator("Eva", 9);
user1.increment();
In ES6 the class keyword was introduced. The class keyword is no more than syntactic sugar on top of the already existing prototypal inheritance pattern. Classes in JavaScript is basically another way of writing constructor functions which can be used in order to create new object using the new keyword.