14. Factories and Classes
Tags: javascript, webdev, beginners, programming
Published: 2022-02-08 13:11:35

### **Articles**

- [https://exploringjs.com/impatient-js/ch_proto-chains-classes.html](https://exploringjs.com/impatient-js/ch_proto-chains-classes.html) 90% explanation about prototype chaining
- [https://www.javascriptjanuary.com/blog/es6-classes](https://www.javascriptjanuary.com/blog/es6-classes) 100% new keyword protection
- [How To Use Classes in JavaScript — Tania Rascia](https://www.digitalocean.com/community/tutorials/understanding-classes-in-javascript) 100% mage & hero instance of subclasses __proto__
- [Javascript Classes — Under The Hood — Majid](https://medium.com/tech-tajawal/javascript-classes-under-the-hood-6b26d2667677) 100% class = mix of constructor function and prototypes, problems of constructor function & prototypes
- [Class vs Factory function: exploring the way forward — Cristi Salcescu](https://medium.freecodecamp.org/class-vs-factory-function-exploring-the-way-forward-73258b6a8d15)
- [How ES6 classes really work and how to build your own — Robert Grosse](https://medium.com/@robertgrosse/how-es6-classes-really-work-and-how-to-build-your-own-fd6085eb326a) 50%
- [An Easy Guide To Understanding Classes In JavaScript](https://dev.to/lawrence_eagles/an-easy-guide-to-understanding-classes-in-javascript-3bcm) 100% Developer & Person
- [https://javascript.plainenglish.io/factories-are-still-better-than-classes-in-javascript-47f15071904e](https://javascript.plainenglish.io/factories-are-still-better-than-classes-in-javascript-47f15071904e) factory vs class

---

In Javascript, there are two ways for creating objects; factories and classes. 
## Factories
Factory function is a function that returns object.
``` jsx
const RocketShipFactory = (c) => {
  const color = c;
  
  return {
    fly: () => console.log(`The ${color} rocketship has launched.`),
    land: () => console.log(`The ${color} rocketship has landed.`)
  } 
}

const spaceX = RocketShipFactory('black');
spaceX.fly();
```
Above snippet is an simple factory function for making `spaceX` object.
### Closure
What thing that gets my interest is that factory pattern usually uses closure for data encapsulation. In above snippet, `color` variable is unaccessible in global scope but we can access it indirectly through `fly` or `land` method.
``` jsx
console.log(spaceX.color); // undefined
```
---
Classes are just 'syntactic sugar' of prototypal inheritance. Purpose of class is to set up the prototype chain between class.prototype and instances. Let's look at prototype first.
## Prototype
In javascript, every objects are linked each other through something called 'prototype chain'.
### Class is just template of prototype
One thing that is very important is that instances created by class links to class.prototye, not class itself.
``` jsx
class Person {
  constructor(name) {
    this.name = name;
  }
  describe() {
    return 'Person named '+this.name;
  }
}

const Jane = new Person('jane');
console.log(jane.describe());
``` 
In above snippet, object `Jane` is instance of class `Person`. So, `Jane` is linked to `Person.prototype` with prototype chain, not class `Person` itself.
![](https://images.velog.io/images/gtfo/post/7b81ae12-6c00-4263-b3d2-98b135a8be04/image.png)

### .\__proto__ vs .prototype
Above chart has properties called `__proto__` and `prototype`. What are they?

`__proto__` property is pseudo-property for accessing the prototype of an object. So, `Jane`'s `__proto__` proerty points to the `Person.prototype` object. 

`prototype` property points to the prototype of all instances of class. It means that `Person` class's `prototype` property points to the `Person.prototype`.

Additionally, object `Person.prototype`'s  `constructor` property points to the class itself. 

### All methods (except static) of class are stored in prototype.
Another truth that is important is that all methods except static methods declared inside class are stored in prototype.
![](https://images.velog.io/images/gtfo/post/db7fc403-6d05-4f6d-b4a5-f7b618037ddc/image.png)
Back to pevious example, we can see that `describe` method is actually stored inside the `Person.prototype` object. This is why we call that class is just template/syntatctic sugar of prototypal programming.
But, static methods are stored in class itself.

---
## Classes
### normal & static methods
Normal methods are inherited from classes to instances, but static methods are not inehrited and should use with class itself.

---

### constructor function
Constructor function helps us to intialize with number of parameters which would be assigned as properties of `this`, which is class itself.

---
### Getters/Setters
Getter function uses `get` keyword to get property value and Setter uses `set` keyword to set the property value. It can used for data encapsulation or for using method like property.
``` jsx
class Person {
  constructor(name){
    this._name = name;
  }
  get name() {
    return this._name;
  }
}

const Jane = new Person('jane');
console.log(Jane.name); // 'jane'
Jane.name = "alex";
console.log(Jane.name); // 'jane'
```
We can hide `_name` property and it would not be modified. Also, we can call `name` method like a property.

---
### Subclasses
With subclasses, we can make class which is simiar or extended from the original classes.
``` jsx
class Person {
  constructor(name) {
    this.name = name;
  }

sayName() {
    console.log("My name is " + this.name);
  }
}

class Developer extends Person {
  constructor(name) {
    super(name);
    this.name = name;
  }

getBio() {
    super.sayName();
    console.log("I am a developer");
  }
}

let ReactGuy = new Developer("Lawrence Eagles");
ReactGuy.getBio(); // "My name is Lawrence Eagles"
	           // "I am a developer"
```
#### extend keyword
`extend` keyword makes subclasses.
#### super keyword
`super` keyword is used to access and call functions from the object's parent ( original class). In above snippet, `super.sayName()` calls `sayName` method of class `Person`. One thing to check is that `this` in `sayName` method refers to `ReactGuy` instance, not class itself. 

If the `super` keyword is called inside the constructor, it calls the constructor function of parent class. For example, `super(name)` is called inside `Developer` constructor function. So, parameter variable `name` will be passed to the constructor function of `Person` class. 
#### Prototype relation
When subcalss is created from original class, original class becomes the subcalss' prototype. For example, class `Person` is the `Developer`'s prototype.
``` jsx 
class Person {
  constructor(name) {
    this.name = name;
  }
  describe() {
    return `Person named ${this.name}`;
  }
  static logNames(persons) {
    for (const person of persons) {
      console.log(person.name);
    }
  }
}

class Employee extends Person {
  constructor(name, title) {
    super(name);
    this.title = title;
  }
  describe() {
    return super.describe() +
      ` (${this.title})`;
  }
}

const jane = new Employee('Jane', 'CTO');
assert.equal(
  jane.describe(),
  'Person named Jane (CTO)');
```
In above snippet, `Employee` is subclass of `Person` and `Jane` is instance of subclass `Employee`. Prototype chain looks as following chart.
![](https://images.velog.io/images/gtfo/post/b3916b19-4bef-49e6-8d64-8233c16df580/image.png)

---
## Factory vs Classes
Both has some different advantages and disadvantages.
### Data Encapsulation
First, sector is data encapsulation. In factory, we can control if we want data to be private or public by using closure. However, in classes, it's not that simple.
#### Classes; data encapsulation / getter & setter
As I mentioned, getter & setter is used for data encapsulation in classes. However, it's not systemically encapsulated. What it means by that is it's actually modifiable.
``` jsx 
class Person {
  constructor(name){
    this._name = name;
  }
  get name() {
    return this._name;
  }
}

const Jane = new Person('jane');
console.log(Jane.name);
Jane._name = "alex";
console.log(Jane.name);
```
If we reassign the property `_name`, the value returned from `name` method changes. Although, in javascript, we conventionally promise not to modify variable with `_` prefix. But it's possible.
#### Classes; data encapsulation / # prefix
\# prefix is introduced recently for private class field.
``` jsx
class CoffeeMachine {
  #waterLimit = 200;

  #checkWater(value) {
    if (value < 0) throw new Error(".");
    if (value > this.#waterLimit) throw new Error(".");
  }

}

let coffeeMachine = new CoffeeMachine();

coffeeMachine.#checkWater(); // Error
coffeeMachine.#waterLimit = 1000; // Error
```
It looks nice, but one problem is that private methods in classes are also not accessible in subclasses.

---
### this keyword
In class, `this` keyword goes through some scope confusion in certain situations. These situations are when `this` is used in nested function or in callback function.

The solution to this problem is **arrow function**.
``` jsx
class Car {
  constructor(maxSpeed){
    this.maxSpeed = maxSpeed;
  }
  drive = () => {
    console.log(`driving ${this.maxSpeed} mph!`)
  }
}
```
This works find for any circumstances.

---
### Memory cost
Memory cost is problem to factory function. Unlike to class which only stores methods once in prototype, factory fuctions create copy of each methods on every instances they create. This could be problematic if the number of instances increase.