JavaScript - Fonctionnalités

-

Fonctionnalités principales

JavaScript possède plusieurs fonctionnalités principales qui en font un langage de programmation puissant et flexible pour le développement web. Ces fonctionnalités comprennent les variables et types de données, les opérateurs, le flux de contrôle et les fonctions.

Variables et types de données

En JavaScript, vous pouvez déclarer des variables en utilisant les mots-clés var, let, ou const. var est la façon traditionnelle de déclarer des variables, tandis que let et const ont été introduits dans ES6 (ECMAScript 2015) pour fournir une portée de bloc et l'immuabilité.

JavaScript possède plusieurs types de données primitifs :

Type de données Description
number Représente des valeurs numériques, à la fois des entiers et des nombres à virgule flottante
string Représente des données textuelles, entourées de guillemets simples ou doubles
boolean Représente une valeur logique, soit true soit false
null Représente une absence délibérée de valeur ou une valeur nulle
undefined Représente une variable qui a été déclarée mais à laquelle aucune valeur n'a été assignée

JavaScript a également un type de données object, qui peut contenir des collections de paires clé-valeur ou des structures plus complexes.

JavaScript est un langage à typage dynamique, ce qui signifie que les variables peuvent contenir des valeurs de n'importe quel type de données, et que le type d'une variable peut changer pendant l'exécution. Cette flexibilité est obtenue grâce à la coercition et à la conversion de type, où JavaScript convertit automatiquement les valeurs d'un type à un autre lorsque c'est nécessaire.

Opérateurs

JavaScript fournit une gamme d'opérateurs pour effectuer des opérations sur les valeurs :

  • Opérateurs arithmétiques : +, -, *, /, %, ++, --
  • Opérateurs d'affectation : =, +=, -=, *=, /=, %=
  • Opérateurs de comparaison : ==, ===, !=, !==, >, <, >=, <=
  • Opérateurs logiques : &&, ||, !
  • Opérateur ternaire : condition ? valeur1 : valeur2

Flux de contrôle

JavaScript offre plusieurs instructions de flux de contrôle qui vous permettent de contrôler l'exécution du code en fonction de certaines conditions ou de répéter des blocs de code plusieurs fois.

  • Instructions if...else : Exécutent un bloc de code si une condition spécifiée est vraie, ou un autre bloc de code si la condition est fausse
  • Instruction switch : Évalue une expression et exécute le bloc de code correspondant en fonction du cas correspondant
  • Boucle for : Répète un bloc de code un nombre spécifié de fois
  • Boucles while et do...while : Répètent un bloc de code tant qu'une condition spécifiée est vraie
  • Instructions break et continue : Modifient le flux des boucles en terminant la boucle ou en passant à l'itération suivante

Fonctions

Les fonctions sont des blocs de code réutilisables qui effectuent des tâches spécifiques. En JavaScript, vous pouvez définir des fonctions en utilisant le mot-clé function suivi du nom de la fonction et d'un ensemble de parenthèses contenant des paramètres optionnels.

Conseil: Déclaration de fonction

function saluer(nom) {
  console.log("Bonjour, " + nom + " !");
}

Les fonctions peuvent accepter des paramètres en entrée et renvoyer des valeurs en utilisant le mot-clé return. Elles peuvent être appelées par leur nom suivi de parenthèses contenant les arguments requis.

JavaScript prend également en charge les expressions de fonction, où les fonctions peuvent être assignées à des variables ou passées comme arguments à d'autres fonctions.

Conseil: Expression de fonction

const carre = function(x) {
  return x * x;
};

Les fonctions fléchées, introduites dans ES6, fournissent une syntaxe concise pour définir des fonctions, particulièrement lorsqu'elles sont utilisées comme callbacks ou dans des modèles de programmation fonctionnelle.

Conseil: Fonction fléchée

const multiplier = (a, b) => a * b;

Ces fonctionnalités principales forment la base de JavaScript et sont essentielles pour écrire des programmes de base à complexes dans le développement web. Comprendre et maîtriser ces fonctionnalités vous permettra de créer des applications web dynamiques et interactives.

Fonctionnalités avancées

JavaScript possède de nombreuses fonctionnalités avancées qui vous permettent d'écrire du code plus complexe et efficace. Ces fonctionnalités incluent les objets et les tableaux, les classes et l'héritage, la programmation asynchrone et la gestion des erreurs.

Objets et tableaux

Les objets et les tableaux sont des structures de données importantes en JavaScript. Les objets stockent des collections de paires clé-valeur, tandis que les tableaux stockent des listes ordonnées de valeurs.

Pour créer un objet, vous pouvez utiliser la notation littérale d'objet ou le constructeur Object. Vous pouvez accéder et modifier les propriétés d'un objet en utilisant la notation par point ou la notation par crochets.

Conseil: Création et accès aux propriétés d'un objet

const person = {
  name: "John",
  age: 30,
  city: "New York"
};

console.log(person.name); // Sortie : "John"
person.age = 31;
console.log(person["city"]); // Sortie : "New York"

Les tableaux sont créés en utilisant la notation littérale de tableau ou le constructeur Array. Vous pouvez accéder et modifier les éléments d'un tableau en utilisant leur index.

Conseil: Création et accès aux éléments d'un tableau

const fruits = ["apple", "banana", "orange"];

console.log(fruits[0]); // Sortie : "apple"
fruits[1] = "grape";
console.log(fruits); // Sortie : ["apple", "grape", "orange"]

Les objets et les tableaux disposent de méthodes intégrées qui vous permettent d'effectuer des opérations courantes, comme ajouter ou supprimer des éléments, rechercher des valeurs et modifier des données.

JavaScript prend également en charge la déstructuration, qui vous permet d'extraire des valeurs d'objets et de tableaux et de les attribuer à des variables de manière concise.

Conseil: Déstructuration d'objets et de tableaux

const { name, age } = person;
console.log(name); // Sortie : "John"

const [first, second] = fruits;
console.log(second); // Sortie : "grape"

Classes et héritage

JavaScript prend en charge la programmation orientée objet grâce aux classes et à l'héritage. Les classes sont des plans pour créer des objets avec des propriétés et des méthodes spécifiques.

Pour définir une classe, vous utilisez le mot-clé class suivi du nom de la classe. À l'intérieur de la classe, vous pouvez définir une méthode constructeur pour initialiser les propriétés de l'objet et d'autres méthodes pour définir le comportement de l'objet.

Conseil: Définition d'une classe

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

Vous pouvez créer des instances d'une classe en utilisant le mot-clé new suivi du nom de la classe et des arguments requis.

Conseil: Création d'une instance de classe

const rect = new Rectangle(5, 3);
console.log(rect.getArea()); // Sortie : 15

JavaScript prend également en charge l'héritage, vous permettant de créer de nouvelles classes basées sur des classes existantes. Vous pouvez utiliser le mot-clé extends pour créer une sous-classe qui hérite des propriétés et des méthodes d'une superclasse.

Conseil: Héritage en JavaScript

class Square extends Rectangle {
  constructor(side) {
    super(side, side);
  }
}

const square = new Square(4);
console.log(square.getArea()); // Sortie : 16

Les sous-classes peuvent remplacer les méthodes de la superclasse en utilisant le même nom de méthode. Elles peuvent également appeler la méthode de la superclasse en utilisant le mot-clé super.

Programmation asynchrone

JavaScript est un langage monothread, ce qui signifie que le code est exécuté séquentiellement. Cependant, JavaScript fournit des moyens de gérer les opérations asynchrones, comme les requêtes HTTP ou la lecture de fichiers, sans bloquer l'exécution d'autres codes.

Par le passé, la programmation asynchrone en JavaScript était réalisée à l'aide de callbacks. Un callback est une fonction passée en argument à une autre fonction et exécutée lorsque l'opération asynchrone est terminée.

Conseil: Programmation asynchrone avec des callbacks

function fetchData(callback) {
  // Simulation d'une opération asynchrone
  setTimeout(() => {
    const data = "Hello, world!";
    callback(data);
  }, 1000);
}

fetchData((data) => {
  console.log(data); // Sortie : "Hello, world!"
});

Cependant, les callbacks peuvent conduire à un code imbriqué et complexe, connu sous le nom de "callback hell". Pour résoudre ce problème, JavaScript a introduit les Promesses, qui offrent une meilleure façon de gérer les opérations asynchrones.

Les Promesses représentent la réussite ou l'échec éventuel d'une opération asynchrone et vous permettent d'enchaîner plusieurs opérations asynchrones à l'aide des méthodes .then() et .catch().

Conseil: Programmation asynchrone avec des Promesses

function fetchData() {
  return new Promise((resolve, reject) => {
    // Simulation d'une opération asynchrone
    setTimeout(() => {
      const data = "Hello, world!";
      resolve(data);
    }, 1000);
  });
}

fetchData()
  .then((data) => {
    console.log(data); // Sortie : "Hello, world!"
  })
  .catch((error) => {
    console.error(error);
  });

ES2017 a introduit les mots-clés async et await, qui fournissent une syntaxe ressemblant davantage à du code synchrone pour travailler avec les Promesses. À l'intérieur d'une fonction async, vous pouvez utiliser le mot-clé await pour mettre en pause l'exécution jusqu'à ce qu'une Promesse soit résolue.

Conseil: Programmation asynchrone avec async/await

async function fetchData() {
  // Simulation d'une opération asynchrone
  const data = await new Promise((resolve) => {
    setTimeout(() => {
      resolve("Hello, world!");
    }, 1000);
  });
  return data;
}

fetchData().then((data) => {
  console.log(data); // Sortie : "Hello, world!"
});

La boucle d'événements et la pile d'appels de JavaScript fonctionnent ensemble pour gérer l'exécution du code synchrone et asynchrone. La boucle d'événements vérifie constamment la pile d'appels et la file d'attente des tâches, exécutant les tâches de la file d'attente lorsque la pile d'appels est vide.

Gestion des erreurs

La gestion des erreurs est un aspect important de l'écriture de code JavaScript robuste. JavaScript fournit l'instruction try...catch pour gérer les exceptions qui peuvent survenir pendant l'exécution du code.

Vous pouvez envelopper le code susceptible de générer une erreur dans un bloc try, et spécifier le code pour gérer l'erreur dans le bloc catch.

Conseil: Gestion des erreurs avec try...catch

try {
  // Code susceptible de générer une erreur
  throw new Error("Quelque chose s'est mal passé !");
} catch (error) {
  console.error(error.message); // Sortie : "Quelque chose s'est mal passé !"
}

Vous pouvez utiliser le mot-clé throw pour lancer vos propres erreurs ou des objets d'erreur personnalisés. Cela vous permet de gérer différemment des types d'erreurs spécifiques.

Conseil: Lancer des erreurs personnalisées

function divide(a, b) {
  if (b === 0) {
    throw new Error("Division par zéro !");
  }
  return a / b;
}

try {
  console.log(divide(10, 0));
} catch (error) {
  console.error(error.message); // Sortie : "Division par zéro !"
}

Fonctionnalités ES6+

JavaScript a évolué au fil des années, et ECMAScript 2015 (ES6) a introduit de nouvelles fonctionnalités largement adoptées dans le développement JavaScript moderne. Ces fonctionnalités visent à rendre le langage plus expressif, concis et facile à utiliser. Voici quelques-unes des fonctionnalités ES6+ notables.

Littéraux de gabarit

Les littéraux de gabarit, également connus sous le nom de chaînes de caractères de gabarit, offrent un moyen de créer et de manipuler des chaînes en JavaScript. Ils présentent deux avantages principaux par rapport à la concaténation de chaînes traditionnelle :

  1. Chaînes multi-lignes : Les littéraux de gabarit permettent de créer des chaînes multi-lignes sans avoir besoin de caractères d'échappement ou de concaténation. Vous pouvez envelopper le contenu de votre chaîne dans des backticks ( ) et inclure des sauts de ligne directement dans la chaîne.

Conseil: Chaîne multi-ligne

const chaineMultiLigne = `
  Ceci est une
  chaîne multi-ligne
  utilisant des littéraux de gabarit.
`;
  1. Interpolation de chaînes : Les littéraux de gabarit prennent en charge l'interpolation de chaînes, ce qui permet d'intégrer directement des expressions ou des variables dans la chaîne. En encadrant l'expression ou la variable dans ${}, vous pouvez incorporer des valeurs dynamiques dans vos chaînes.

Conseil: Interpolation de chaîne

const nom = "Jean";
const age = 30;
const message = `Je m'appelle ${nom} et j'ai ${age} ans.`;
console.log(message); // Sortie : "Je m'appelle Jean et j'ai 30 ans."

Affectation par décomposition

L'affectation par décomposition est une façon d'extraire des valeurs d'objets ou de tableaux et de les assigner à des variables. Elle offre une syntaxe concise pour déballer les valeurs des structures de données.

  1. Décomposition d'objet : La décomposition d'objet permet d'extraire des propriétés spécifiques d'un objet et de les assigner à des variables du même nom.

Conseil: Décomposition d'objet

const personne = {
  nom: "Jean",
  age: 30,
  ville: "Paris"
};

const { nom, age } = personne;
console.log(nom); // Sortie : "Jean"
console.log(age); // Sortie : 30
  1. Décomposition de tableau : La décomposition de tableau permet d'extraire des valeurs d'un tableau en fonction de leur position et de les assigner à des variables.

Conseil: Décomposition de tableau

const nombres = [1, 2, 3, 4, 5];
const [a, b, ...reste] = nombres;
console.log(a); // Sortie : 1
console.log(b); // Sortie : 2
console.log(reste); // Sortie : [3, 4, 5]

L'affectation par décomposition prend également en charge les valeurs par défaut, utilisées lorsque la valeur extraite est indéfinie, et permet de renommer les variables lors du processus d'affectation.

Fonctions fléchées

Les fonctions fléchées offrent une syntaxe concise pour définir des fonctions en JavaScript. Elles constituent une alternative compacte aux expressions de fonction traditionnelles.

  1. Syntaxe concise : Les fonctions fléchées éliminent le besoin du mot-clé function et utilisent la syntaxe => pour définir la fonction.

Conseil: Fonction fléchée - Syntaxe concise

const saluer = (nom) => {
  return `Bonjour, ${nom} !`;
};
console.log(saluer("Jean")); // Sortie : "Bonjour, Jean !"

Si le corps de la fonction consiste en une seule expression, vous pouvez omettre les accolades et le mot-clé return, rendant la syntaxe encore plus concise.

Conseil: Fonction fléchée - Expression unique

const carre = (x) => x * x;
console.log(carre(5)); // Sortie : 25
  1. Liaison lexicale de this : Les fonctions fléchées ont une liaison lexicale de this, ce qui signifie qu'elles héritent de la valeur this de la portée environnante. Ce comportement est utile lorsqu'on travaille avec des méthodes d'objet ou des fonctions de rappel.

Conseil: Fonction fléchée - Liaison lexicale de 'this'

const personne = {
  nom: "Jean",
  saluer: function() {
    setTimeout(() => {
      console.log(`Bonjour, ${this.nom} !`);
    }, 1000);
  }
};
personne.saluer(); // Sortie : "Bonjour, Jean !" (après 1 seconde)

Modules

ES6 a introduit un système de modules standardisé pour JavaScript, permettant d'organiser le code en modules réutilisables et encapsulés. Les modules offrent un moyen de définir et de partager du code entre différents fichiers ou projets.

  1. Exportation de modules : Pour rendre une valeur, une fonction ou une classe disponible dans d'autres modules, vous devez l'exporter à l'aide du mot-clé export.

Conseil: Exportation de modules

// math.js
export function ajouter(a, b) {
  return a + b;
}

export const PI = 3.14159;
  1. Importation de modules : Pour utiliser des valeurs, des fonctions ou des classes d'un autre module, vous devez les importer à l'aide du mot-clé import.

Conseil: Importation de modules

// main.js
import { ajouter, PI } from './math.js';

console.log(ajouter(2, 3)); // Sortie : 5
console.log(PI); // Sortie : 3.14159

Les modules prennent également en charge les exportations par défaut, qui permettent d'exporter une seule valeur comme exportation par défaut d'un module, et les exportations nommées, qui permettent d'exporter plusieurs valeurs nommées d'un module.

Opérateurs de reste et de décomposition

Les opérateurs de reste et de décomposition (...) offrent un moyen de travailler avec plusieurs éléments de manière concise.

  1. Paramètres du reste : L'opérateur de reste permet de capturer plusieurs arguments passés à une fonction sous forme de tableau.

Conseil: Paramètres du reste

function somme(...nombres) {
  return nombres.reduce((acc, curr) => acc + curr, 0);
}
console.log(somme(1, 2, 3, 4, 5)); // Sortie : 15
  1. Opérateur de décomposition : L'opérateur de décomposition permet de répartir les éléments d'un tableau ou d'un objet dans un autre tableau ou objet.

Conseil: Opérateur de décomposition

const nombres = [1, 2, 3];
const nouveauxNombres = [...nombres, 4, 5];
console.log(nouveauxNombres); // Sortie : [1, 2, 3, 4, 5]

const personne = { nom: "Jean", age: 30 };
const nouvellePersonne = { ...personne, ville: "Paris" };
console.log(nouvellePersonne); // Sortie : { nom: "Jean", age: 30, ville: "Paris" }

Ce sont quelques-unes des fonctionnalités ES6+ notables qui ont été introduites en JavaScript. D'autres fonctionnalités incluent les paramètres de fonction par défaut, les littéraux d'objet améliorés, les classes, les promesses, et plus encore. Ces fonctionnalités ont grandement amélioré l'expressivité, la lisibilité et la fonctionnalité du langage, rendant le développement JavaScript plus agréable et efficace.