Intro to ES6 Classes
Tags: javascript, codenewbie
Published: 2020-10-18 12:39:26

One of my favorite new features from ES6 is the new way of implementing classes. To understand the new way to instantiate classes you must first understand how **constructors** and **prototypes** work. This is because ES6 classes are *syntactical sugar*. You may be thinking: what exactly is syntactical sugar? 

Well, Techopedia defines syntactical sugar as: 
>"a term for syntax changes in computer programming which make it easier for humans to code." 

In other words, it makes our code easier to read and easier to understand. 

Sounds good to me, sign me up for some ***candygrammar***!  ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/utcyjf46ox89ghe8icqr.jpg)


**_Prototypes and constructors explained_**
-----
So what's a prototype? Simply put, *a prototype is an object that allows other objects to use shared properties*. Most objects are instances of Object. That may sound confusing, so here is an example: 

```javascript
const student = {
name: 'A name',
lastName: 'A last name',
coder: true
}

console.log(student.valueOf()) // {name: 'A name', lastName: 'A last name', coder: true}
```
Wait, how did we call a method of `.valueOf` if it doesn't exist on the student object? This is where **_prototype chains_** come into play. The browser will initially check to see if the student object has a method called `valueOf` available. If it doesn't it looks to the parent prototype and in this case it is the Object class. If Object did not have a `valueOf` method the console would print `undefined` 

### Well what about constructors? 
A constructor is *a function that creates an instance of a class*
```javascript
function User(name, email){
this.name = name
this.email = email
}

const UserA = new User('Sally' 'SallyJ@gmail.com')
console.log(UserA) // User {name: 'Sally', email: 'SallyJ@gmail.com'}
```

#####When a constructor is invoked:
* an empty object is created
* the created object is returned as the constructor's value implicitly, notice no `return` keyword being used.
* The `this` keyword will refer to the newly created object.

If you are new to the concepts of inheritance, prototypes, and constructors and still find yourself confused after my examples above; I suggest using [Udemy](http://www.Udemy.com) or [coderwall](http://www.coderwall.com) to get better acquainted, since these two are **crucial** to understanding how ES6 classes work.

######*Okay enough about what's happening under the hood.*

Here's why I think ES6 Classes are so great:
1. The `class` keyword
   * The `class` keyword creates a new class with our name of choice. It's best practice to use a capital letter when declaring a class e.g.: `class Student{}`. I like this feature because it explicitly states that we are creating a new class. No guesswork, or second thought required.
2. `Static` methods
   * MDN defines a static method as a method that is *"called without instantiating their class and are also not callable when the class is instantiated. Static methods are often used to create utility functions for an application."* In layman's terms static methods have no access to data stored in specific objects. With ES6 we now have the ability to declare a static method on a parent class and have it available to their subclasses as well.
3. `Super` & `Extends` keywords
   * The super keyword can be used in 2 ways: 
     1. As a function: `super` can be used as a function that calls upon the parent class with the parameters passed to the sub or child class. This ensures that the sub class is in fact an `instanceof` the parent class.
     2. As an object: The `super` keyword can also be used as an object so that the child class can call the methods of the parent class explicitly.


####*How it started*
This is how a class would be declared and modified prior to ES6
```javascript
function Person(name, age){
this.name = name
this.grade = grade
}

Person.prototype.greeting = function(){
return 'Hi, my name is' + this.name + 'nice to meet you.'
}

Person.prototype.extraInfo = function(){
return 'I am' + this.age + 'and my favorite thing to do is...'
}
```
If we wanted to extend these properties to a subclass, it would look like
```javascript
function Child(name, age){
   Person.call(this, name, age)
}

Child.prototype = Object.create(Person.protoype)
Child.prototype.constructor = Child;

Child.prototype.chores = function(){
return 'My name is' + this.name 'I am' + this.age +
'and I have to mop the floor, wash the dishes, and do the laundry'  
}
```
####*How it's going*
This is how class instantion and inheritance looks now
```javascript
class Person {
 constructor(name, age){
   this.name = name
   this.age = age
}

greeting() {
  return `Hi my name is ${this.name}, nice to meet you!
}

extraInfo() {
  return `I am ${this.age} and my favorite thing to do is...`
}
}

class Child extends Person {
 constructor(name, age){
    super(name, age)
}

chores() {
  return `My name is ${this.name}, I am ${this.age} 
and I have to mop the floor, wash the dishes, and do the laundry`
}
}

const Mary = new Child('Mary', '7')
console.log(Amelia.greeting()) // Hi my name is Mary, nice to meet you
```

#####*see how much easier the ES6 version is to read and understand?*
>It's important to note that the underlying functionality hasn't changed, but the new syntax provides a nice style to classes that make it much more readable and developer friendly.

####Now it's your turn
Try out the ES6 class instantiation pattern and features. 
*I promise you'll never turn back.*