OOP in JavaScript
We han inherit by Object.create(<baseobject>)
.
Constructor functions
new
keyword automatically return the object. new
changes this
to the object which we would like to create.
Example:
function Elf(name, weapon) {
this.name = name;
this.weapon = weapon;
}
Elf.prototype.attack = function () {
console.log(`${this.name} attacks with ${this.weapon}`);
};
const elf1 = new Elf('Peter', 'stones');
const elf2 = new Elf('Vasya', 'fire');
elf1.attack();
elf2.attack();
We can’t use arrow function to create an attach
function, because arrow functions are lexically scouped and this
will be equal to the global object:
// wrong way:
Elf.prototype.attack = () => {
console.log(`${this.name} attacks with ${this.weapon}`);
};
But regular functions are dynamically scoped
Using functions inside of methods.
In case we using functions inside of methods, this will be working a bit diffrent way. There are the following ways how to fix this:
Elf.prototype.build = function () {
function building() {
return `${this.name} build a house`;
}
building.call(this);
};
or
Elf.prototype.build = function () {
let self = this;
function building() {
return `${self.name} build a house`;
}
building();
};
ES6 Classes
The same with classes:
class Elf {
constructor(name, weapon) {
this.name = name;
this.weapon = weapon;
}
attack() {
console.log(`${this.name} attacks with ${this.weapon}`);
}
}
const elf1 = new Elf('Peter', 'stones');
elf1.attack();
This is actually a syntax sugar.
Summarise of this
There are 4 ways:
new
binding this
function Person(name, age) {
this.name = name;
this.age = age;
}
implicit binding
const person = {
name: 'Vasya',
age: 44,
hi() {
console.log(`Hi ${this.name}`);
}
}
explicit binding
const person = {
name: 'Vasya',
age: 44,
hi: function () {
console.log(`Hi ${this.name}` + this.setTimeout);
}.bind(window),
};
arrow functions
const person = {
name: 'Vasya',
age: 44,
hi: function () {
const inner = () => this.setTimeout
console.log(`Hi ${this.name}` + inner());
}.bind(window),
};
Inheritance
Example:
class Charackter {
constructor(name, weapon) {
this.name = name;
this.weapon = weapon;
}
attack() {
console.log(`${this.name} attacks with ${this.weapon}`);
}
}
class Elf extends Charackter {
constructor(name, weapon, type) {
super(name, weapon);
this.type = type;
}
}
class Ogre extends Charackter {
constructor(name, weapon, color) {
super(name, weapon);
this.color = color;
}
makeFort() {
console.log(`${this.name} colored with ${this.color} has created a fort`);
}
}
Private or Public
It works only for ES2020
class Ogre extends Charackter {
age = 56;
constructor(name, weapon, color) {
super(name, weapon);
this.color = color;
}
private makeFort() {
console.log(`${this.name} colored with ${this.color} has created a fort`);
}
}