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