Variables and Types
The fundamentals of modern variables
Modern JavaScript: Variables, Types, and Data Structures
In this tutorial, we will explore the fundamentals of modern JavaScript: how to declare variables, understand the different data types, work with operators, and use the essential data structures.
JavaScript is a dynamic and flexible language that has evolved considerably since its creation. With the arrival of ES6 (ECMAScript 2015) and later versions, the language now offers powerful, modern features.
Declaring Variables
In modern JavaScript, there are three ways to declare variables:
let
let lets you declare variables whose scope is limited to the block in which they are defined:
let age = 25;
age = 26; // Reassignment is allowed
if (true) {
let message = "Hello"; // Variable limited to this block
console.log(message); // "Hello"
}
// console.log(message); // Error: message is not defined
const
const lets you declare constants whose value cannot be reassigned:
const PI = 3.14159;
// PI = 3.14; // Error: cannot reassign a constant
const personne = { nom: "Alice" };
personne.nom = "Bob"; // Allowed - the contents can change
// personne = {}; // Error: cannot reassign the reference
var (the old way)
var was the only way to declare variables before ES6. Its scope is either function-level or global:
var x = 10;
var x = 20; // Redeclaration is allowed (problematic)
if (true) {
var y = 30; // Scope is not limited to the block
}
console.log(y); // 30 - y is accessible here
Best Practices
In modern JavaScript, prefer:
constby default for any variable that will not be reassignedletwhen reassignment is necessary- Avoid
varunless you are working with legacy code
Data Types
JavaScript is a dynamically typed language, which means you don’t need to declare the type of a variable.
Primitive Types
1. Number
JavaScript uses a single type for all numbers:
const entier = 42;
const decimal = 3.14;
const exponentiel = 2.5e5; // 250000
const binaire = 0b1010; // 10
const octal = 0o744; // 484
const hexadecimal = 0xFF; // 255
// Special values
const infini = Infinity;
const pasUnNombre = NaN; // Not a Number
// Checks
console.log(isNaN(pasUnNombre)); // true
console.log(isFinite(infini)); // false
2. String
JavaScript offers several ways to create strings:
// Single quotes
const prenom = 'Marie';
// Double quotes
const nom = "Dupont";
// Template literals (backticks) - ES6
const age = 30;
const message = `${prenom} ${nom} a ${age} ans.`;
// Useful methods
console.log(prenom.toUpperCase()); // MARIE
console.log(" texte ".trim()); // "texte"
console.log("abc,def".split(",")); // ["abc", "def"]
console.log("Hello".includes("ell")); // true
3. Boolean
const estMajeur = true;
const estInscrit = false;
// Conditional expressions
const a = 5;
const b = 10;
console.log(a < b); // true
console.log(a === b); // false (strict equality)
console.log(a >= 5); // true
4. Undefined
undefined represents a variable that has been declared but has no assigned value:
let resultat;
console.log(resultat); // undefined
// Check
console.log(typeof resultat === 'undefined'); // true
5. Null
null represents the deliberate absence of a value:
const donnees = null;
// Watch out for the pitfall
console.log(typeof null); // "object" (historical JavaScript bug)
console.log(donnees === null); // true (use strict equality)
6. Symbol (ES6)
Symbol creates unique, immutable identifiers:
const id1 = Symbol('id');
const id2 = Symbol('id');
console.log(id1 === id2); // false - each Symbol is unique
7. BigInt (ES2020)
To represent integers of arbitrary size:
const grandNombre = 1234567890123456789012345678901234567890n;
const autreFacon = BigInt("9007199254740991");
console.log(typeof grandNombre); // "bigint"
Reference Types (Objects)
1. Object
Objects are collections of key-value pairs:
// Creating an object literal
const personne = {
prenom: "Jean",
nom: "Dupont",
age: 30,
adresse: {
ville: "Paris",
codePostal: "75001"
}
};
// Accessing properties
console.log(personne.prenom); // "Jean"
console.log(personne["nom"]); // "Dupont"
// Adding/modifying properties
personne.email = "jean.dupont@example.com";
personne.age = 31;
// Object methods
const cles = Object.keys(personne); // ["prenom", "nom", "age", "adresse", "email"]
const valeurs = Object.values(personne); // ["Jean", "Dupont", 31, {...}, "jean..."]
2. Array
Arrays are ordered collections of values:
// Creating an array
const fruits = ["pomme", "banane", "cerise"];
const mixte = [1, "deux", true, null, { clé: "valeur" }];
// Accessing elements (zero-indexed)
console.log(fruits[0]); // "pomme"
// Useful methods
fruits.push("orange"); // Adds to the end
fruits.pop(); // Removes the last element
fruits.unshift("fraise"); // Adds to the beginning
fruits.shift(); // Removes the first element
// forEach loop
fruits.forEach((fruit, index) => {
console.log(`${index}: ${fruit}`);
});
// Transformation methods (do not modify the original array)
const fruitsMajuscules = fruits.map(fruit => fruit.toUpperCase());
const fruitsCourts = fruits.filter(fruit => fruit.length < 6);
const total = [1, 2, 3, 4].reduce((acc, val) => acc + val, 0); // 10
3. Function
In JavaScript, functions are first-class objects:
// Function declaration
function saluer(nom) {
return `Bonjour, ${nom} !`;
}
// Function expression
const direAuRevoir = function(nom) {
return `Au revoir, ${nom} !`;
};
// Arrow function (ES6)
const multiplier = (a, b) => a * b;
// Function as a parameter
function executerFonction(fn, valeur) {
return fn(valeur);
}
console.log(executerFonction(saluer, "Marie")); // "Bonjour, Marie !"
4. Date
const maintenant = new Date();
const dateSpecifique = new Date("2023-12-31T23:59:59");
const timestamp = dateSpecifique.getTime(); // milliseconds since January 1, 1970
5. Map and Set (ES6)
// Map - collection of key-value pairs (keys of any type)
const utilisateurs = new Map();
utilisateurs.set('u1', { nom: "Alice", age: 25 });
utilisateurs.set('u2', { nom: "Bob", age: 30 });
// Set - collection of unique values
const nombres = new Set([1, 2, 3, 3, 4, 4, 5]); // {1, 2, 3, 4, 5}
Type Checking
To check the type of a variable, use the typeof operator:
console.log(typeof "hello"); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof { a: 1 }); // "object"
console.log(typeof [1, 2, 3]); // "object" (arrays are objects in JS)
console.log(typeof function() {}); // "function"
For arrays, use Array.isArray():
console.log(Array.isArray([1, 2, 3])); // true
Type Conversion
JavaScript often performs implicit conversions, but you can also do them explicitly:
// Conversion to string
const num = 42;
const numStr = String(num); // "42"
const autreMethode = num.toString(); // "42"
// Conversion to number
const str = "42";
const strNum = Number(str); // 42
const parseMethode = parseInt(str, 10); // 42 (base 10)
const parseFloat = parseFloat("3.14"); // 3.14
// Conversion to boolean
const valeurBool = Boolean(1); // true
// false for: 0, "", null, undefined, NaN, false
Operators
Arithmetic Operators
const a = 10;
const b = 3;
const addition = a + b; // 13
const soustraction = a - b; // 7
const multiplication = a * b; // 30
const division = a / b; // 3.3333...
const modulo = a % b; // 1 (remainder of the division)
const puissance = a ** b; // 1000 (ES2016)
// Increment and decrement
let compteur = 0;
compteur++; // compteur = 1
compteur--; // compteur = 0
Comparison Operators
const a = 10;
const b = "10";
// Equality (with type coercion)
console.log(a == b); // true
// Strict equality (without coercion)
console.log(a === b); // false
// Inequality (with coercion)
console.log(a != b); // false
// Strict inequality (without coercion)
console.log(a !== b); // true
// Comparisons
console.log(a > 5); // true
console.log(a <= 10); // true
Logical Operators
const x = true;
const y = false;
// Logical AND
console.log(x && y); // false
// Logical OR
console.log(x || y); // true
// Logical NOT
console.log(!x); // false
// Short-circuiting (useful for default values)
const nom = null;
const nomAffiche = nom || "Utilisateur inconnu"; // "Utilisateur inconnu"
Nullish Coalescing Operator (ES2020)
const valeur = null;
const resultat = valeur ?? "Valeur par défaut"; // "Valeur par défaut"
// Different from || because it only uses the default value if the value is null or undefined
Optional Chaining Operator (ES2020)
const utilisateur = {
profil: {
// adresse: { ville: "Paris" }
}
};
// Without optional chaining (risk of error)
// const ville = utilisateur.profil.adresse.ville; // Error!
// With optional chaining
const ville = utilisateur.profil?.adresse?.ville; // undefined
Spread Operator
// For arrays
const tab1 = [1, 2, 3];
const tab2 = [...tab1, 4, 5]; // [1, 2, 3, 4, 5]
// For objects
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
Destructuring (ES6)
Destructuring lets you extract values from arrays or objects concisely:
// Array destructuring
const nombres = [1, 2, 3, 4, 5];
const [premier, deuxieme, ...reste] = nombres;
console.log(premier); // 1
console.log(deuxieme); // 2
console.log(reste); // [3, 4, 5]
// Object destructuring
const personne = { prenom: "Alice", nom: "Dupont", age: 30 };
const { prenom, age, profession = "Inconnue" } = personne;
console.log(prenom); // "Alice"
console.log(age); // 30
console.log(profession); // "Inconnue" (default value)
// Renaming properties
const { prenom: firstName } = personne;
console.log(firstName); // "Alice"
// Nested destructuring
const utilisateur = {
id: 1,
infos: {
nom: "Durand",
contact: {
email: "durand@example.com"
}
}
};
const { infos: { contact: { email } } } = utilisateur;
console.log(email); // "durand@example.com"
Control Structures
JavaScript offers the usual control structures, with a few modern particularities.
Conditionals
// if, else if, else
const age = 18;
if (age < 18) {
console.log("Mineur");
} else if (age === 18) {
console.log("Tout juste majeur");
} else {
console.log("Majeur");
}
// Ternary operator
const statut = age >= 18 ? "majeur" : "mineur";
Loops
// Classic for
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// for...of (to iterate over the values of an iterable)
const fruits = ["pomme", "banane", "cerise"];
for (const fruit of fruits) {
console.log(fruit);
}
// for...in (to iterate over the properties of an object)
const personne = { nom: "Dupont", prenom: "Jean", age: 30 };
for (const prop in personne) {
console.log(`${prop}: ${personne[prop]}`);
}
// while
let compteur = 0;
while (compteur < 5) {
console.log(compteur);
compteur++;
}
// do...while
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
Switch
const jour = "Lundi";
switch (jour) {
case "Lundi":
console.log("Début de semaine");
break;
case "Mercredi":
console.log("Milieu de semaine");
break;
case "Vendredi":
console.log("Fin de semaine");
break;
default:
console.log("Autre jour");
}
Basic Input and Output
Console
// Output
console.log("Message simple");
console.info("Information");
console.warn("Avertissement");
console.error("Erreur");
// Formatted output
console.log("Nom: %s, Âge: %d", "Alice", 30);
// Grouping
console.group("Détails utilisateur");
console.log("Nom: Alice");
console.log("Âge: 30");
console.groupEnd();
// Table
console.table([
{ nom: "Alice", age: 25 },
{ nom: "Bob", age: 30 }
]);
// Measuring time
console.time("Timer");
// Long-running operations...
console.timeEnd("Timer"); // Displays the elapsed time
User Interaction (Browser)
// Display a message
alert("Attention !");
// Ask for confirmation
const confirmation = confirm("Êtes-vous sûr ?");
if (confirmation) {
console.log("L'utilisateur a confirmé");
}
// Ask for input
const nom = prompt("Quel est votre nom ?", "Utilisateur");
console.log(`Bonjour, ${nom}`);
Complete Example
Here is an example that uses several of the concepts we have learned:
// Program that calculates the average of a list of numbers
// Define an arrow function to calculate the average
const calculerMoyenne = (nombres) => {
if (nombres.length === 0) return 0;
const somme = nombres.reduce((acc, val) => acc + val, 0);
return somme / nombres.length;
};
// Function to compare a number to the average
const comparerAvecMoyenne = (nombre, moyenne) => {
if (nombre > moyenne) return "supérieur à";
if (nombre < moyenne) return "inférieur à";
return "égal à";
};
// Main program
try {
// In a real environment, these values could come from a user interface
const nombres = [15, 20, 25, 10, 30];
// Display the numbers
console.log("Nombres:", nombres.join(", "));
// Calculate and display the average
const moyenne = calculerMoyenne(nombres);
console.log(`La moyenne est: ${moyenne.toFixed(2)}`);
// Compare each number to the average
console.log("\nComparaison avec la moyenne:");
nombres.forEach((nombre, index) => {
const relation = comparerAvecMoyenne(nombre, moyenne);
console.log(`Nombre ${index + 1} (${nombre}) est ${relation} la moyenne.`);
});
// Filter the numbers greater than the average
const nombresSuperieurs = nombres.filter(nombre => nombre > moyenne);
console.log(`\nNombres supérieurs à la moyenne: ${nombresSuperieurs.join(", ")}`);
} catch (erreur) {
console.error("Une erreur est survenue:", erreur.message);
}
Key Differences from Other Languages
If you know other programming languages, here are some notable differences in JavaScript:
-
Dynamic typing: There’s no need to declare types; they are determined at runtime.
-
First-class functions: Functions can be assigned to variables, passed as arguments, and returned by other functions.
-
Prototypes vs. classes: JavaScript uses a prototype-based system, although class syntax was introduced in ES6.
-
Hoisting: Variable and function declarations are “hoisted” to the top of their scope.
-
Events and callbacks: JavaScript relies heavily on callbacks and promises to handle asynchronous code.
-
Loose vs. strict equality:
==performs type coercion, while===does not.
Best Practices
To write clean, maintainable modern JavaScript:
-
Use
constby default, useletif you need to reassign, and avoidvar. -
Prefer arrow functions for short functions and callbacks.
-
Use destructuring to extract values from objects or arrays.
-
Use template literals for multiline strings or strings with interpolation.
-
Avoid loose comparisons (
==,!=); prefer strict comparisons (===,!==). -
Use default parameters and spread operators.
-
Adopt modern array methods like
map,filter, andreduceinstead of traditional loops when appropriate. -
Handle asynchronous code properly with Promises and async/await (which we’ll cover in an upcoming tutorial).
Practice Exercises
To solidify your knowledge, try these exercises:
-
Write a function that takes an array of numbers and returns the sum of the even numbers.
-
Create an object representing a book with properties such as title and author, and a method to display this information.
-
Write a function that takes a string and returns an object containing the number of occurrences of each character.
-
Create a function that converts a temperature from Celsius to Fahrenheit or vice versa, depending on a mode parameter.
-
Use destructuring to swap the values of two variables without using a temporary variable.
Conclusion
In this tutorial, we explored the fundamentals of modern JavaScript:
- The different ways to declare variables (
let,const,var) - Data types (primitive and reference)
- Operators (arithmetic, comparison, logical)
- Destructuring and spread operators
- Control structures (conditionals and loops)
- Basic input/output
These concepts are the foundation on which you’ll build your understanding of modern JavaScript. As you progress, you’ll discover how these elements fit together to create dynamic, interactive web applications.
In the next tutorial, we’ll explore modern functions and their new features.
Need to review the basics? Check out our introductory tutorial.
Ready to continue? Move on to the next tutorial on functions.
Comments
Comments are powered by GitHub Discussions
Sign in with GitHub to join the discussion