Javascript concepts introduced in ES6

Fri Aug 12 2022

JavascriptES6ConceptsFrontendProgramming

1. Arrow functions

Traditional function looks like this: function myFunc() { ... }

Arrow function looks like this: const myFunc = () => { ... }

Arrow functions help us to avoid issues with the this keyword, as in an arrow function, this will always refer to the same thing without changing the context during the run time.

Also, arrow functions can really simplify the syntax of your code in case of really simple functions. Let's take the example of a basic mathematical operation:

In the traditional function syntax, it would look as follows:

function sum(number) {return (number + 2)}
sum(2) // 4

Now let's look how it would look as an arrow function:

const sum = number => number + 2

That simple!

Remember, that the parentheses fall only if you have one parameter, if you have no or more than one parameter, you cannot omit the parentheses. The same is valid for the body of the function — you can drop the curly ==brackets== and the return keyword only and only if the body consists of just one line.

2. Classes

Classes are a more convenient way of creating construction functions. They also support inheritance, so you can use them to create new classes with the same properties (variables attached to classes) and methods (functions attached to classes), and add new properties and methods. This is the same concept as the prototypes.

class Animal {
    constructor() {
        this.type = 'cow'
    }
    printAnimalType() {
        console.log(this.type)
    }
}

If you are creating another class which derives from (or more precisely extends) the first class, you have to add the super() keyword before altering or adding new properties.

class Dog extends Animal {
    constructor() {
        super()
        this.name = 'Dandy'
        this.type = 'dog'
    }

    printDogName() {
        console.log(this.name)
    }
}

const dandy = new Dog()

dandy.printDogName() // Dandy
dandy.printAnimalType() // dog

But, hey, you now know that we can't write modern JavaScript without simplifying the syntax, right?

ES6 JavaScript has brought us more simplified syntax of the class properties and methods, and it looks prettier!

Adding property in pre-ES6 : constructor () {this.newProperty = 'value'}

Adding property in post-ES6: myProperty = 'value'

As you can see, we can now drop the constructor() function call.

As per the methods, you can (should?) now use arrow functions to declare methods and spare yourself some this trouble.

Let's apply it to the previous example:

class Animal {
    type = 'cow'

    printAnimalType = () => {
        console.log(this.type)
    }
}

class Dog extends Animal {
    name = 'Dandy'

    type = 'dog'

    printDogName = () => {
        console.log(this.name)
    }
}

const dandy = new Dog()
dandy.printDogName() //  Dandy
dandy.printAnimalType() // dog

3. Spread and Rest Operators

It's just one operator, actually — ...

Spread operator allow us to take an array or an object and add new elements to it without altering the original. (Read: immutability)

const newArray = [...oldArray, newElement1, newElement2]

const newObject = {...oldObject, newProp1: 'a', newProp2: 'b'}

Rest operator is used in function properties, when you don't need, don't want or simply cannot specify the exact number of the parameters.

const uppercaseArgs = (...args) = args.toUpperCase()

Examples

Spread operator to an array:
const numbers = [1, 2, 3]
const newNumbers = [...numbers, 4, 5, 6]
console.log(newNumbers) // [1, 2, 3, 4, 5, 6]

If you remove the spread operator, the newNumbers will just include the numbers array in the new array.

const newNumbers = [numbers, 4, 5, 6]
console.log(newNumbers) // [[1, 2, 3], 4, 5, 6]
Let's apply it to an object:
const dog = { name: 'Dandy' }
const newDog = { ...dog, type: awesome }
console.log(newDog) // { name: Dandy type: awesome }
Rest operator in a function

Rest operator in a function is not as frequently used as spread operators, but is not less useful.

const filter = (...args) => {
    return args.filter((el) => el === 1)
}
console.log(filter(1, 2, 3)) // [1]

Keep in mind your result will always be an array.

4. Destructuring

React developers are (or at least should be) familiar with destructuring. After all, we use for the state management with the useState hook all the time.

Destructuring an array

Destructuring an array, compared to a spread operator which gives you all the elements, is a selective way of using the elements of an array.

Example:

[a, b] = ['Dandy', 'Laima']
console.log(a) // Dandy 
console.log(b) // Laima

You can also namingly take elements of an existing array.

const numbers = [1, 2, 3] 
[num1, , num3] = numbers 
console.log(num1, , num3) // the console will show numbers 1 and 3
Destructuring an object

Destructuring an object follows the similar idea — it allows you to extract a specific variable from an object with its property:

let { name } = { name: 'Dandy', type: 'Dog' }
console.log(name) // Dandy
console.log(type) // undefined

Made with Next.JS, Tailwind CSS, GraphCMS and Lots of