Object Oriented Programming (Building blocks) - PintoGideon/Recursive-React-Tree-Component GitHub Wiki
OOP building blocks
let user1={
name:'Will',
score:3,
increment:function(){user1.increment++}
};
user1.increment();
Factory Functions
If we want to create an empty object, we use Object.create(null)
.
let user2=Object.create(null) // user2={}
user2.score=3;
user2.name='Jim';
user2.increment=function(){
user2.score++
}
Our code is getting repetitive though. Let's abstract the repetitive functionalities.
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();
Hey, do you notice that the increment function
performs the same functionality and we are storing it twice. It can be abstracted out even further. How can repeated functionality be shared between users? We don't want to manually add a feature on for each user.
Prototype chain
function userCreator(name,score){
const newUser=Object.create(userFunctionStore)
newUser.score=score;
newUser.name=name;
return newUser
}
const userFunctionStore={
increment:function(){this.score++},
login:function(){console.log('Logged in')
}
const user1=userCreator('Gideon',100);
const user2=userCreator('Amod',50);
user1.increment() //101
user2.increment() //51
Wait a minute !! The object that is returned does not appear to have the increment
method on it?
Under the hood there is a hidden property on the received object which has a wire to userFunctionStore
.
{
name:"Gideon"
score:100
__proto__:userFunctionStore
}
When the JS engine does not find a method on the object, it looks up to the object's prototype chain (through it's __proto__
) reference to the object where the method's are store. Also, this
is always created implicitly in the function's environment to set context.
Let's do one more thing.
user1.hasOwnProperty('score')
I don't really see hasOwnProperty
method in the userFunctionStore
though. Where is this method store so that the user1
knows about it.
Object.prototype={
hasOwnProperty:function(){}
}
userFunctionStore={
increment:function(){},
login:function(){},
__proto__:Object.prototype
}
Prototypal nature of JavaScript
The new
keyword automates the hard work of creating a new user object manually and returning it.
function userCreator(name,score){
this.name=name;
this.score=score;
}
userCreator.prototype.increment=function(){
this.score++
}
Interlude - Functions are both objects and functions
function multiplyBy2(num){
return num*2
}
multiplyBy2.stored=4
multuplyBy2.stored=4
multiplyBy2.prototype={}
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);
Now I cannot look at the userCreator
function and assume that it requires the new
keyword to run.
Class keyword
The class
keyword is just syntactic sugar.
class UserCreator(){
constructor(name,score){
this.name=name;
this.score=score
}
increment(){
this.score++
}
login(){
console.log('Login')
}
}