Next-Gen JavaScript - Level Up
Handy JavaScript ES6/ES7 concepts for beginners
In this article, I'll provide a brief introduction to some core next-gen JavaScript concepts, of course focusing on the ones you'll use the most in your coding joruney. And I'll also include handy code snippets for better understanding just like forever!
Contents
let & const
let
and const
basically replace var
. let
is very similar to var
with the difference that the let
variable has a block-level scope (i.e. the enclosing { }
just like variables in other languages). On the other hand, the scope of a var
variable is the entire enclosing function.
Let's have a look at an example:
function varDemo() {
var x = 1;
{
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letDemo() {
let x = 1;
{
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
Use const
instead of var
if you plan on never re-assigning this "variable". It's a good practice to assign arrays and objects as a const
.
const number = 2;
try {
number = 99;
} catch (err) {
console.log(err);
// expected output: TypeError: invalid assignment to const `number'
}
console.log(number);
// expected output: 2
Read more about let
here.
Read more about const
here.
ES6 Arrow Functions
Arrow functions are an alternate way of creating functions in JavaScript. Besides a shorter syntax, they offer advantages when it comes to keeping the scope of the this
keyword.
// Traditional Function
function callMe(a) {
console.log(a);
}
// Arrow Function Break Down
// 1. The above function can be written as:
const callMe = function(a) {
console.log(a);
}
// 2. Remove the word "function" and place arrow between the argument
// and opening body bracket
const callMe = (a) => {
console.log(a);
}
Important:
When having no arguments, you have to use empty parentheses in the function declaration:
const callMe = () => { console.log('Something!'); }
When having exactly one argument, you may omit the parentheses:
const callMe = name => { console.log(name); }
When just returning a value, you can use the following shortcut:
const returnMe = name => name; // That's equal to: const returnMe = name => { return name; }
Read more about ES6 Arrow functions here.
Exports & Imports
In all modern JavaScript projects, you split your code across multiple JavaScript files - so-called modules. You do this to manage your large code base and make it understandable.
To access functionality in another file, you need export
(to make it available) and import
(to get access) statements.
export
You got two different types of exports: default (unnamed) and named exports:
default export
const user = { id: 1, name: 'SomeName' } // Export user export default user
named export
// export individual features (can export var, let, // const, function, class) export const initialize = () => { ... } export const BASE_URL = 'https://xyz... ' // Or export features declared earlier like this: export { initialize, BASE_URL };
Important
A file can only contain one default and an unlimited amount of named exports. You can also mix the one default with any amount of named exports in one and the same file.
import
You can import default exports like this:
import someNameOfYourChoice from './path/to/file.js';
Surprisingly,
someNameOfYourChoice
is totally up to you.Named exports have to be imported by their name:
import { someData } from './path/to/file.js';
When importing named exports, you can also import all named exports at once with the following syntax:
import * as upToYou from './path/to/file.js';
upToYou
is, well, up to you and simply bundles all exported variables/functions in one JavaScript object.
For example, if youexport const someData = ...
, you can access it onupToYou
like this:upToYou.someData
Read more about export
here.
Read more about import
here.
Classes
Classes are a feature that basically replaces constructor functions and prototypes. You can define blueprints for JavaScript objects with them just like other OOP languages.
Like this:
class User {
constructor () {
this.name = 'SomeName';
}
}
const user = new User();
console.log(user.name); // prints 'SomeName'
The syntax you see above is the "old" syntax for defining properties. In modern JavaScript projects, you can use the following, more convenient way of defining class properties:
class User {
name = 'SomeName';
}
const user = new User();
console.log(user.name); // prints 'SomeName'
You can also define methods. Either like this:
class User {
name = 'SomeName';
printName () {
console.log(this.name); // this is required to refer to the class!
}
}
const user = new User();
user.printName(); // prints 'SomeName'
Or like this:
class User {
name = 'SomeName';
printName = () => {
console.log(this.name);
}
}
const user = new User();
user.printName(); // prints SomeName
The second approach has the same advantage as all arrow functions have: The this
keyword doesn't change its reference.
You can also use inheritance when using classes:
class Human {
gender = 'male';
}
class User extends Human {
name = 'SomeName';
printName = () => {
console.log(this.name);
}
}
const user = new User();
user.printName(); // prints 'SomeName'
console.log(user.gender); // prints 'male'
Read more about class
here.
Spread & Rest Operator
The spread and rest operators actually use the same syntax: ...
Yes, it's just three dots! Its usage determines whether you're using it as the spread or rest operator.
Spread Operator
The spread operator allows you to pull elements out of an array (split the array into a list of its elements) or pull the properties out of an object.
Here are two examples:
// spread operator used on array
const oldArray = [1, 2, 3];
const newArray = [...oldArray, 4, 5]; // This now is [1, 2, 3, 4, 5];
// spread operator used on an object
const oldObject = {
name: 'SomeName'
};
const newObject = {
...oldObject,
age: 23
};
// newObject would then be
{
name: 'SomeName',
age: 23
}
Note
The spread operator is extremely useful for cloning arrays and objects. Since both are reference types (and not primitives), copying them safely can be tricky. With the spread operator, you have an easy way of creating a clone of the object or array.
Rest Operator
The rest operator allows a function to accept an indefinite number of arguments as an array.
Here's how you use it:
const filter = (...args) => {
return args.filter(el => el === 1)
}
console.log(filter(1, 2, 3)) // prints [1]
Read more about spread operator here.
Read more about rest operator here.
Destructuring
Destructuring allows you to easily access the elements of arrays or objects and assign them to variables.
Here's an example for destructuring an array:
const array = [1, 2, 3];
const [a, b] = array;
console.log(a); // prints 1
console.log(b); // prints 2
console.log(array); // prints [1, 2, 3]
And here for destructuring an object:
const user = {
name: 'SomeName',
age: 23
}
const {name} = user;
console.log(name); // prints 'SomeName'
console.log(age); // prints undefined
console.log(user); // prints {name: 'SomeName', age: 23}
Destructuring is very useful when working with function arguments. Consider this example:
const printName = (user) => {
console.log(user.name);
}
printName({name: 'SomeName', age: 23}); // prints 'SomeName'
The above code forces us to call user.name
inside of our function. We can condense this code with destructuring:
const printName = ({name}) => {
console.log(name);
}
printName({name: 'SomeName', age: 23}); // prints 'SomeName'
We get the same result as above but we save some code. By destructuring, we simply pull out the name
property and store it in a variable/argument named name
which we can then use in the function body.
Read more about Destructuring here.
That's all folks! Do let me know what you liked and what can be improved in the comments below! Also, feel free to drop me a line if you don't understand something. ✌
Thanks for reading!