JavaScript

In order to understand how Frontity works and be able to modify its files and develop your own project, it is necessary to understand the main JavaScript concepts that we use in our code. The number of concepts can seem overwhelming, but most of them are pretty simple.

Note this guide's purpose is to give you a better understanding of which JavaScript concepts we use at Frontity and a brief explanation of them. If you want a more detailed way of learning JavaScript, you can check other guides like freeCodeCamp or w3schools.

JavaScript Concepts

Comments

As with most programming languages, you are able to include comments in your code. You can write single-line comments with // and multi-line comments between /*...*/

// Single-line comment.
/*
Multi-line comment.
*/

Variables

You can store data inside variables in order for it to be used later. For creating one you just have to define it and assign a value.

var number1 = 3;
var number2 = 2;
var total = number1 + number2 // Total value would be 5.

JavaScript variables can hold many data types: numbers, strings, objects and more.

Since the ES6 update there are other ways of declaring variables. We explain them later ES6 variables (let, const).

Strings

Strings are used for storing text and can be defined between double or single quotes.

var text1 = "This is a string";
var text2 = 'This is also a string';

(Optional) There are some specific methods to work with strings that could be useful. To see some examples refer to this guide.

Since the ES6 update there is also a new way of declaring strings that is more versatile than single or double quotes. We explain this later in ES6 template strings.

Numbers

Numbers can be written with or without decimals.

var number1 = 5; // This is a number.
var number2 = 5.6; // This is also a number.

(Optional) There are some specific methods to work with numbers too. You can view this guide to see some examples.

Objects

Objects are also variables, and they can store multiple values by assigning values to properties. You define objects this way:

var person = {
  firstName: "Jon",
  lastName: "Snow",
  age: 40
};

This way, we have the variable person with as many properties-values as we want. You can access/modify the value of a specific property in two different ways:

var name1 = person.firstName;
var name2 = person["firstName"]; // Both return the same value.

Object properties can also store other objects, like this:

var person = {
  name: {
    first: "Jon",
    last: "Snow"
  },
  age: 40
};

Arrays

Arrays store multiple values as a list of items.

var pets = ['dog', 'cat', 'turtle'];

You can store as many items as you want, and they don't need to be strings, they can be anything you want, even objects. In order to access/modify an array item, you have to specify its position (starting at 0):

var item1 = pets[0]; // Returns 'dog'.
var item2 = pets[1]; // Returns 'cat'.
var item3 = pets[2]; // Returns 'turtle'.

Arrays are an important part of JavaScript and there are lots of array methods that can simplify your code. You can check out an extended list of them at w3schools array reference. We consider the following especially interesting:

  • myArray.forEach(): to run a function for each array element.

  • myArray.filter(): to create a new array with every element in an array that pass a test.

  • myArray.map(): to create a new array with the result of calling a function for each array element.

Functions

A JavaScript function is a chunk of code intended to perform a specific task. You have to define it first and call it later. You can pass parameters to the function to return a different value depending on the parameters.

// Defining the function.
function myFunction(parameter1, parameter2) {
  return parameter1 + parameter2;
}
// Calling the function with specific parameters.
myFunction(2, 3); // It will return 5.
myFunction(5, 4); // It will return 9.

Since the ES6 update there are other ways of declaring functions that are commonly used and make your code easier to understand. We explain them later in ES6 arrow functions.

Operators

In JavaScript, there are many types of operators. We could divide them this way:

  • Arithmetic Operators: To perform arithmetics like addition ( + ), subtraction (-), multiplication (*), etc.

  • Assignment Operators: To assign values to variables (=).

  • Comparison Operators: To test if a condition is true/false. It could be x === y, x < 5, x > 20...

  • Logical Operators: To add some logic to the comparison statement. For example in this statementx < 5 && y > 25 "x" must be less than 5 AND "y" must be more than 25.

These are just some examples of JavaScript operators, there is a good summary at w3schools JavaScript Operators to fully understand them.

In JavaScript the == and != operators exist, but they are never used because sometimes they don't behave properly (i.e. 0 == "" is true!). For that reason everybody always uses three equals: === and !== for comparisons.

If-else

Conditional statements are used to run different code based on different conditions. You can define an if-else statement this way:

if (condition1) {
  // Run this code if condition1 is true.
} else if (condition2) {
  // Run this code if condition2 is true.
} else {
  // Run this code if condition1 and condition 2 are both false.
}

You can add as many else if (each one with a condition) as you want, and it will run the code of the first one that matches true. Moreover, you can use if-else without any else if, or even without the else statement, and it will continue with the rest of the code if condition1 is false.

In React, if-else statements don't work. Instead, we have to use operators and ternary expressions. For more details, refer to React basics - Special cases.

Ternary operator

In JavaScript there's another way to do conditionals: using ternary operators.

condition ? /* Runs when condition is true */ : /* Runs when condition is false */;

They are useful when defining variables, like this:

// Assign the color blue when age is above 30 and yellow when it is below. 
var color = person.age > 30 ? "blue" : "yellow"

They are also useful in React, but we'll see that later.

Switch

Switch statements are similar to if-else, and they let you run different code depending on a condition. This is the way to define them:

switch(value) {
  case 1:
    // Run this code if value === 1.
    break;
  case 2:
    // Run this code if value === 2.
    break;  
  default:
    // Run this code if no case match.
}

Again, you can define as many cases as you want, and if none of them match, the default would run.

For loops

This statement is really useful if you want to perform the same code a number of times but with different values. To do so you have to define 3 statements:

for (i = 0; i < 5; i += 1) {
  // Code block to be executed.
}
  • Statement 1 (i = 0): The initial value when the loop starts.

  • Statement 2 (i < 5): The condition that has to match to finish the loop.

  • Statement 3 (i += 1): This is optional and is executed after each loop iteration. Usually used to change the value before running the next loop iteration.

It is common to use for loops to run the same code for every array item. In these cases, we strongly recommend using the forEach() method instead.

While loops

Related to for loops, while loops perform the same code while a condition is true. You have to make sure that you change the condition in the code so you don't create infinite loops.

while (condition1) {
  // Code block to be executed.
}

There is a similar loop called do/while which is a variant of the while loop. The only difference is that it will execute the code block once, before checking if the condition is true, and continue while the condition is true.

do {
  // Code block to be executed.
}
while (condition);

Regular Expressions (Regular expression)

The Regular Expressions (Regular expression) are really useful in JavaScript as they let you match a pattern. They can be used, for example, for defining a more complex condition.

They can be overwhelming, so if you are not familiar with them don't worry. We would recommend you try to understand each particular case as you find them in our code and know that they exist as they could be useful in your code. Again, don't worry and just learn the concepts once you need them. This way, you will learn step by step and it will be easier.

To learn the basics and help you understand or create some RegExps, you can use w3schools guide, freeCodeCamp regular expression and also RegExr to test them.

ES6 concepts

There are some features introduced with the ES6 update that are widely used across Frontity:

Variables (let and const)

We previously defined variables with the statement var; however, since ES6, it is not used at all. Instead, people use let and const :

  • Const is used almost 100% of the time in Frontity, and it implies that the variable can't be reassigned, it has a constant value.

  • Let is used when you want to iterate through your variable and you would like to reassign its value.

There are slight differences between let and var too, and you can read about them here, but they are not that important and var is not commonly used anymore.

Arrow functions

Arrow functions are a new way of defining functions that make them shorter. Here you can see an example of how to declare the same function with and without arrow functions:

Without arrow functions

const hello = function(name){
    return 'Hi ' + name + ', nice to meet you!';
}
hello('Jon');

With arrow functions

const hello = (name) => {
    return 'Hi ' + name + ', nice to meet you!'
};
hello('Jon');

As you can see, the common way of using them is deleting the word function and adding => just after it.

Sometimes the syntax can be even smaller. If your function is just composed of a return statement, you can change the curly braces { } for parentheses ( ), delete the return statement, and it will return the whole function automatically.

const hello = (name) => (
    'Hi ' + name + ', nice to meet you!'
);
hello('Jon');

You can avoid the parentheses too:

const hello = (name) => 'Hi ' + name + ', nice to meet you!';
hello('Jon');

However, if you return an object, the parentheses are required:

const hello = (name) => ({ firstName: name, lastName: "Snow" });
hello('Jon'); // Outputs { firstName: "Jon", lastName: "Snow" }.

Note that if we don't want the function to return, for example if we are defining variables inside it, we must use the curly braces.

Finally, we can remove the parenthesis from the parameters if only one parameter is used:

const hello = name => "Hi " + name + ", nice to meet you!";

const hello2 = (name, surname) => "Hi " + name + surname + ", nice to meet you!";

Default parameters

You can set a default value for a parameter and it will be used if no other value is passed. To do so, you can use the operator = while defining the parameter.

const hello = (name = "there") => "Hi " + name + ", nice to meet you" ;

hello("Jon"); // It will return "Hi Jon, nice to meet you".
hello(); // It will return "Hi there, nice to meet you".

Destructuring assignment

This JavaScript expression is used to unpack values from arrays or objects properties. It can seem a bit weird at the beginning, but once you get used to it, it will remove a lot of lines of code from your project.

Object destructuring

As mentioned before, destructuring an object lets you assign the value of one property to a variable.

const person = {
    name: "Jon",
    lastName: "Snow",
    age: 30
};
const { name, lastName } = person;

// You are assigning the value of person.name to a new variable called "name".
console.log(name); // Returns Jon.
console.log(lastName); // Returns Snow.
console.log(age); // ERROR: age is not defined.

As you can see above, you select all the variables you want to create using curly braces { } which equates them to the object properties you want to get the values from. Here you have an example of how to assign values with/without destructuring:

// With destructuring.
const { name, lastName, age } = person; 

// Without destructuring.
const name = person.name; 
const lastName = person.lastName;
const age = person.age;

We are only defining three variables above, but imagine if you had to define many variables!

You can also assign a different name to the variables if you want. For example:

const { name: a, lastName: b } = person

console.log(a); // Returns person.name.
console.log(b); // Returns person.lastName.

This way you are getting the value of person.name and storing it in a variable called "a".

Moreover, you can define a default value for a variable as mentioned before, just in case the object doesn't have that property defined.

const person = {
    name: "Jon",
    lastName: "Snow",
    age: 30
};
const { name, lastName, family = "Stark" } = person;

console.log(family); // Returns Stark even though it's not defined in person.

Array destructuring

They work in a similar way to objects:

const items = [10, 20, 30, 40, 50];
const [a, b] = items;

console.log(a); // Returns 10.
console.log(b); // Returns 20.

Again, it is the same as object destructuring, but instead of using curly braces we use [ ] because we are working with arrays, and it will get values depending on the position.

You can also use default values in case the array length is smaller than the variables defined.

const items = [10, 20];
const [a = 35, b = 45, c = 55] = items;

console.log(a); // Returns 10.
console.log(b); // Returns 20.
console.log(c); // Returns 55.

Since items has just two elements, the first two variables are assigned values from the array while c gets its default value.

If you have any questions or you want more information about array and object destructuring, refer to MDN Web Docs for a more detailed explanation.

Template strings

Template strings (also called template literals) are just an easier way to work with strings. To define them you have to use back-ticks ( `` ). The main advantages of template strings are:

  • They allow embedded expressions.

  • You can use multi-line strings, just by adding a line-break.

Here is an example:

const name = "Jon Snow";

const text = `Hi there!
I am ${name},
and I have killed ${43 + 57} white walkers`;

There are more advantages of working with template strings, and you can check them out in guides like MDN web docs or Google docs.

In Frontity, we will mainly use them for styling, but you can find them in other parts of the code as well.

Import and export

JavaScript lets you export functions (including components), classes, objects, or anything else from one module in order to be used in other programs. The same way you can reuse the ones written by external programs.

The import and export statements are exactly for this. If you want anything from your module/file to be reused somewhere else, you will use export, and if you want to use anything external, you will use import.

Export

There are two different types of export, named and default, and depending on each one, the corresponding import will be different.

  • Named export: You can have multiple named exports per module. It is useful to export many values, and import just the ones you need.

export const Component1 = () => { /* Code of Component1. */ };
export const Component2 = () => { /* Code of Component2. */ };

You will be exporting two components, with different names. This will be useful in case you want to import just one of them in other files.

You can also export all the variables at once:

const Component1 = () => { /* Code of Component1. */ };
const Component2 = () => { /* Code of Component2. */ };

export {
  Component1,
  Component2
};
  • Default export: You have one default export per module, and it will be used for the default import.

const Component = () => {};

export default Component;

Import

Depending on the export of the source file, the import will be slightly different.

  • From named export: It is mandatory to use the name of the corresponding object and you have to include it between curly braces.

import { Component1, Component2 } from "./file-name"
  • From default export: Importing from a default export, you can use the name you prefer for your file, just don't include it between curly braces.

import Component from "./file-name"

Note that in both methods you have to specify the file you are importing from.

For more info about these statements you can visit the import and export documentation.

When you import stuff from files, you have to use "./" at the beginning. That way, JavaScript knows that it is a file. For example:

import Component from "./file-name"

You can also go deep inside folders:

import Component from "./some-folder/nested-even-more/file-name"

Or go up a level using "../" .

import Component from "../../file-name" // Up two levels from the current folder.

When you import stuff from npm packages (the ones you install with npm install) you have to use the name of the package directly, without any "./" before. Like this:

import Component from "some-package-name"

There are other important ES6 aspects, but understanding the ones above will give you a wide understanding of Frontity's code. Another important concept that is commonly used in React are classes, but since the introduction of hooks, they are no longer needed and are not used at all in Frontity core.

(Optional)For more detailed guides about these concepts, including classes, you can visit https://www.w3schools.com/react/react_es6.asp.

These are the main JavaScript concepts used in Frontity. If you understand them, you will be able to continue with React basics to master Frontity. If you want to delve deeper into learning JavaScript, there are a lot of resources out there, and if you have questions don't hesitate to ask our community โ˜บ๏ธ.

Last updated