/**
 * Allows to log eventual array items.
 * @param {*} array an array.
 * @param {*} title a title describing the array.
 */
const logArrayItems =
    (array = [], title = 'No title') => {
        if (Array.isArray(array) && array.length > 0) {
            console.log(`${title}:`);
            array.forEach((item, index) => console.log(`[${index}]: `, item));
        }
    };
 
/**
 * Allows to build a Regular Expression running result title.
 * 
 * @param {*} appliedMatchFunction name of the applied match function.
 * 
 * @param {*} evaluatedString an evaluated string.
 * 
 * @param {*} appliedRegExp an applied Regular Expression.
 * 
 * @returns a built String corresponding to a Regular Expression result title.
 */
const buildRegExpRunningResultTitle =
    (appliedMatchFunction, evaluatedString, appliedRegExp) =>
        `Result after applying '${appliedMatchFunction}'` +
        ` on '${evaluatedString}' with regular expression '${appliedRegExp}'`;
 
// Expression régulière filtrant tous les mots composés de caractères
// alphabétiques suivi d'un underscore et d'un nombre.
// Deux groupes de capture identifiés:
// - 1er groupe de capture: product
// - 2ème groupe de capture: number
const PRODUCT_FILTER_REG_EXP = /(?<product>[a-z]+)_(?<number>\d+)/gi;
 
const STRING_TO_EVALUATE = 'penA1, computer_150, desktop_5, chair_A, eraser_C, screen_55';
 
const resultForMatch = STRING_TO_EVALUATE.match(PRODUCT_FILTER_REG_EXP) || [];
logArrayItems(
    resultForMatch,
    buildRegExpRunningResultTitle('String#match', STRING_TO_EVALUATE, PRODUCT_FILTER_REG_EXP));
 
const resultForMatchAll = STRING_TO_EVALUATE.matchAll(PRODUCT_FILTER_REG_EXP) || [];
logArrayItems(
    [...resultForMatchAll],
    buildRegExpRunningResultTitle('String#matchAll', STRING_TO_EVALUATE, PRODUCT_FILTER_REG_EXP));

 

 

 

 

 

 

 

 

 
 
const ACURA_CAR = {
    brand: 'Acura',
    model: 'NSX',
    year: 1997,
    color: 'white championship'
}
 
for (const ACURA_CAR_PROPERTY in ACURA_CAR) {
    console.log(`ACURA_CAR#${ACURA_CAR_PROPERTY} = ${ACURA_CAR[ACURA_CAR_PROPERTY]}`);
}
 
/**
 * Allows to retrieve the Global Context before ES2020.
 * 
 * @returns an eventual Global Context.
 * 
 * @throws Error when no Global Context found.
 */
const retrieveGlobalContextBeforeES2020 = () => {
    if (typeof self !== 'undefined') { return self; }
 
    if (typeof window !== 'undefined') { return window; }
 
    if (typeof global !== 'undefined') { return global; }
 
    throw new Error("Not possible to find the global context");
};
 
console.log(retrieveGlobalContextBeforeES2020());
Affichage dans la console si on exécute ce code dans un environnement Node JS :
<ref *1> Object [global] {
  global: [Circular *1],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  },
  queueMicrotask: [Function: queueMicrotask],
  performance: Performance {
    nodeTiming: PerformanceNodeTiming {
      name: 'node',
      entryType: 'node',
      startTime: 0,
      duration: 45.99650000035763,
      nodeStart: 0.7571000009775162,
      v8Start: 3.0175999999046326,
      bootstrapComplete: 32.44829999655485,
      environment: 15.600099995732307,
      loopStart: -1,
      loopExit: -1,
      idleTime: 0
    },
    timeOrigin: 1646566219358.749
  },
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(nodejs.util.promisify.custom)]: [Getter]
  }
}

/**
 * Allows to wait during a specific time defined in milliseconds.
 *
 * @param {*} timeToWaitInMS a time to wait in milliseconds.
 *
 * @returns a Promise.
 */
const wait = (timeToWaitInMS = 0) =>
    new Promise((resolve) => {
        setTimeout(() => {
            resolve(`Promise resolved after ${timeToWaitInMS}ms`);
        }, timeToWaitInMS);
    });
 
/**
* Asynchronous function allowing to wait a specific time in milliseconds
* before ES2020.
* @param {*} timeToWaitInMS a time to wait in milliseconds.
* @returns a Promise
*/
const asyncWaitBeforeES2020 = async (timeToWaitInMS) => {
    const result = await wait(timeToWaitInMS);
 
    return `Result for asynchronous waiting function before ES2020: ${result}`;
};
 
asyncWaitBeforeES2020(1000).
    then((result) => console.log(result))
    .catch((error) => console.error(error));
 
// Since ES2020 it is possible to directly wait for the result of an
// asynchronous operation without encapsulating this processing in
// an asynchronous function.
try {
    const result = await wait(3000);
    console.log('Result for asynchronous waiting function since ES2020:', result);
}
catch (error) {
    console.error(error);
}

 
let theme;
try {
    theme = await import('url_1_to_theme');
} catch {
    theme = await import('url_2_to_theme');
}

import('module.mjs').then((module) => {
    // ...
});
 
// on peut aussi écrire :
async () => {
    const module = await import('module.mjs');
    // ...
};

// --------------------------------- //
// ----------- utils.mjs ----------- //
// --------------------------------- //
 
const PI_VALUE = 3.14;
 
function add(operand1 = 0, operand2 = 0) {
    return operand1 + operand2;
}
 
function substract(operand1 = 0, operand2 = 0) {
    return operand1 - operand2;
}
 
function multiply(operand1 = 0, operand2 = 0) {
    return operand1 * operand2;
}
 
function log(message) {
    console.log(message);
}
 
export { add, substract, multiply, log, PI_VALUE };
 
// --------------------------------- //
// ----------- main.mjs ------------ //
// --------------------------------- //
 
// Module Namespace Exports
export * as utils from './utils.mjs';
 
// ---------------------------------------- //
// ----------- utils_client.mjs ----------- //
// ---------------------------------------- //
 
// Use of 'utils' Module Namespace
import { utils } from './main.mjs';
 
utils.log(utils.add(1, 2)); // 3
 
utils.log(utils.substract(3, 2)); // 1
 
utils.log(utils.multiply(3, 5)); // 15
 
utils.log(utils.PI_VALUE); // 3.14

 

 

 

 

 

 

const UNDERSCORE_CHAR = '_';
const ORIGINAL_STRING = 'testfaketestfaketest';
 
const MY_NEW_STRING_WITHOUT_USING_REGEX = ORIGINAL_STRING.replaceAll('fake', UNDERSCORE_CHAR);
console.log(MY_NEW_STRING_WITHOUT_USING_REGEX); // "test_test_test"
 
const MY_NEW_STRING_BY_USING_REG_EXP_AND_SUBSTITUTE_FUNCTION =
    ORIGINAL_STRING.replaceAll(/fake/g, () => UNDERSCORE_CHAR);
console.log(MY_NEW_STRING_BY_USING_REG_EXP_AND_SUBSTITUTE_FUNCTION); // "test_test_test"
 
console.log(ORIGINAL_STRING); // testfaketestfaketest

// --------------------------------------- //
// ---------- PRIVATE FUNCTIONS ---------- //
// --------------------------------------- //
 
/**
 * Allows to throw an error for a required parameter.
 * 
 * @param {*} parameterName a parameter name.
 * @throws Error.
 */
const throwErrorForRequiredParameter = (parameterName) => {
    throw new Error(`${parameterName} is a required argument.`)
};
 
/**
 * Allows to build a Promise reject message for a specific waiting time.
 * 
 * @param {*} waitingTimeInSeconds a waiting time in seconds.
 * 
 * @returns a message as String.
 */
const buildPromiseRejectMessageForAWaitingTime =
    (waitingTimeInSeconds = throwErrorForRequiredParameter('waitingTimeInSeconds')) =>
        `Promise rejected after ${waitingTimeInSeconds} second(s)`;
 
// --------------------------------------- //
// ----------------- RUN ----------------- //
// --------------------------------------- //
 
const promiseWhichWillBeRejectedAfterOneSecond = new Promise(
    (resolve, reject) => setTimeout(reject, 1000, buildPromiseRejectMessageForAWaitingTime(1)));
 
const promiseWhichWillBeRejectedAfterTwoSeconds = new Promise(
    (resolve, reject) => setTimeout(reject, 2000, buildPromiseRejectMessageForAWaitingTime(2)));
 
const promiseWhichWillBeSuccesfullyResolvedAfterFiveSeconds = new Promise(
    (resolve) => setTimeout(resolve, 5000, 'Promise successfully resolved after 5 seconds'));
 
const promises = [
    promiseWhichWillBeRejectedAfterOneSecond,
    promiseWhichWillBeRejectedAfterTwoSeconds,
    promiseWhichWillBeSuccesfullyResolvedAfterFiveSeconds
];
 
Promise.any(promises).
    then(value => console.log(value))
    .catch(error => console.error(error));

// --------------------------------------- //
// ---------- PRIVATE FUNCTIONS ---------- //
// --------------------------------------- //
 
/**
 * Allows to throw an error for a required parameter.
 * 
 * @param {*} parameterName a parameter name.
 * @throws Error.
 */
const throwErrorForRequiredParameter = (parameterName) => {
    throw new Error(`${parameterName} is a required argument.`)
};
 
/**
 * Allows to build a Promise reject message for a specific waiting time.
 * 
 * @param {*} waitingTimeInSeconds a waiting time in seconds.
 * 
 * @returns a message as String.
 */
const buildPromiseRejectMessageForAWaitingTime =
    (waitingTimeInSeconds = throwErrorForRequiredParameter('waitingTimeInSeconds')) =>
        `Promise rejected after ${waitingTimeInSeconds} second(s)`;
 
// --------------------------------------- //
// ----------------- RUN ----------------- //
// --------------------------------------- //
 
const promiseWhichWillBeRejectedAfterOneSecond = new Promise(
    (resolve, reject) => setTimeout(reject, 1000, buildPromiseRejectMessageForAWaitingTime(1)));
 
const promiseWhichWillBeRejectedAfterTwoSeconds = new Promise(
    (resolve, reject) => setTimeout(reject, 2000, buildPromiseRejectMessageForAWaitingTime(2)));
 
const promiseWhichWillBeRejectedAfterThreeSeconds = new Promise(
    (resolve, reject) => setTimeout(reject, 3000, buildPromiseRejectMessageForAWaitingTime(3)));
 
const promises = [
    promiseWhichWillBeRejectedAfterOneSecond,
    promiseWhichWillBeRejectedAfterTwoSeconds,
    promiseWhichWillBeRejectedAfterThreeSeconds
];
 
Promise.any(promises).
    then(value => console.log(value))
    .catch(error => console.error(error));

// --------------------------------------- //
// ---------- PRIVATE FUNCTIONS ---------- //
// --------------------------------------- //
 
/**
 * Allows to throw an error for a required parameter.
 * 
 * @param {*} parameterName a parameter name.
 * @throws Error.
 */
const throwErrorForRequiredParameter = (parameterName) => {
    throw new Error(`${parameterName} is a required argument.`)
};
 
/**
 * Allows to build a Promise resolution success message for a specific waiting time.
 * 
 * @param {*} waitingTimeInSeconds a waiting time in seconds.
 * 
 * @returns a message as String.
 */
const buildPromiseResolutionSuccessMessageForAWaitingTime =
    (waitingTimeInSeconds = throwErrorForRequiredParameter('waitingTimeInSeconds')) =>
        `Promise successfully resolved after ${waitingTimeInSeconds} second(s)`;
 
// --------------------------------------- //
// ----------------- RUN ----------------- //
// --------------------------------------- //
 
const promiseWhichWillBeSuccesfullyResolvedAfterFiveSeconds = new Promise(
    (resolve) => setTimeout(resolve, 5000, buildPromiseResolutionSuccessMessageForAWaitingTime(5)));
 
const promiseWhichWillBeSuccesfullyResolvedAfterThreeSeconds = new Promise(
    (resolve) => setTimeout(resolve, 3000, buildPromiseResolutionSuccessMessageForAWaitingTime(3)));
 
const promiseWhichWillBeSuccesfullyResolvedAfterTwoSeconds = new Promise(
    (resolve) => setTimeout(resolve, 2000, buildPromiseResolutionSuccessMessageForAWaitingTime(2)));
 
const promises = [
    promiseWhichWillBeSuccesfullyResolvedAfterFiveSeconds,
    promiseWhichWillBeSuccesfullyResolvedAfterThreeSeconds,
    promiseWhichWillBeSuccesfullyResolvedAfterTwoSeconds
];
 
Promise.race(promises).
    then(value => console.log(value))
    .catch(error => console.error(error));

 
 
const promiseWhichWillBeRejectedAfterFiveSeconds = new Promise(
    (resolve, reject) => setTimeout(reject, 5000, 'Promise rejected after 5 seconds'));
 
const promiseWhichWillBeSuccesfullyResolvedAfterTwoSeconds = new Promise(
    (resolve) => setTimeout(resolve, 2000, 'Promise successfully resolved after 2 seconds'));
 
const promises = [
    promiseWhichWillBeRejectedAfterFiveSeconds,
    promiseWhichWillBeSuccesfullyResolvedAfterTwoSeconds,
];
 
Promise.race(promises).
    then(value => console.log(value))
    .catch(error => console.error(error));
 
const promiseWhichWillBeRejectedAfterOneSecond = new Promise(
    (resolve, reject) => setTimeout(reject, 1000, 'Promise rejected after 1 second'));
 
const promiseWhichWillBeSuccesfullyResolvedAfterTwoSeconds = new Promise(
    (resolve) => setTimeout(resolve, 2000, 'Promise successfully resolved after 2 seconds'));
 
const promises = [
    promiseWhichWillBeRejectedAfterOneSecond,
    promiseWhichWillBeSuccesfullyResolvedAfterTwoSeconds,
];
 
Promise.race(promises).
    then(value => console.log(value))
    .catch(error => console.error(error));

const Y = 10;
 
// **************************** //
 
let x;
x &&= Y;
// ici x ne sera pas modifié car il vaut undefined
console.log(x); // undefined
 
// **************************** //
 
x = null;
x &&= Y;
// ici x ne sera pas modifié car il vaut null
console.log(x); // null
 
// **************************** //
 
x = false;
x &&= Y;
// ici x ne sera pas modifié car il vaut false
console.log(x); // false
 
// **************************** //
 
x = 0;
x &&= Y;
// ici x ne sera pas modifié car sa valeur 0
// ne correspond pas à une valeur vraie
console.log(x); // 0
 
// **************************** //
 
x = '';
x &&= Y;
// ici x ne sera pas modifié car
// sa valeur '' (chaîne vide) ne correspond pas à une valeur vraie
console.log(x); // ''
 
// **************************** //
 
x = ' ';
x &&= Y;
// ici x sera modifié car sa valeur ' '
// (chaîne composée d'un espace) correspond à une valeur vraie
console.log(x); // 10
 
// **************************** //
 
x = 1;
x &&= Y;
// ici x sera modifié car sa valeur 1
// correspond à une valeur vraie
console.log(x); // 10
 
// **************************** //
 
x = 2;
x &&= Y;
// ici x sera modifié car sa valeur correspond à une valeur vraie
console.log(x); // 10
 
// **************************** //
 
x = true;
x &&= Y;
// ici x sera modifié car sa valeur correspond à une valeur vraie
console.log(x); // 10 

const Y = 10;
 
// **************************** //
 
let x;
x ||= Y;
// ici x sera modifié car il vaut undefined
console.log(x); // 10
 
// **************************** //
 
x = null;
x ||= Y;
// ici x sera modifié car il vaut null
console.log(x); // 10
 
// **************************** //
 
x = false;
x ||= Y;
// ici x sera modifié car il vaut false
console.log(x); // 10
 
// **************************** //
 
x = 0;
x ||= Y;
// ici x sera modifié car sa valeur 0 
// ne correspond pas à une valeur vraie
console.log(x); // 10
 
// **************************** //
 
x = '';
x ||= Y;
// ici x sera modifié car sa valeur '' (chaîne vide)
// ne correspond pas à une valeur vraie
console.log(x); // 10
 
// **************************** //
 
x = ' ';
x ||= Y;
// ici x ne sera pas modifié car sa valeur ' '
// (chaîne composée d'un espace) correspond à une valeur vraie
console.log(x); // ' '
 
// **************************** //
 
x = 1;
x ||= Y;
// ici x ne sera pas modifié car sa valeur 1
// correspond à une valeur vraie
console.log(x); // 1
 
// **************************** //
 
x = 2;
x ||= Y;
// ici x ne sera pas modifié car sa valeur 2
// correspond à une valeur vraie
console.log(x); // 2
 
// **************************** //
 
x = true;
x ||= Y;
// ici x ne sera pas modifié car sa valeur
// correspond à une valeur vraie
console.log(x); // true

 

const Y = 10;
 
// **************************** //
 
let x;
x ??= Y; // ici x sera modifié car il vaut undefined
console.log(x); // 10
 
// **************************** //
 
x = null;
x ??= Y; // ici x sera modifié car il vaut null
console.log(x); // 10
 
// **************************** //
 
x = false;
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // false
 
// **************************** //
 
x = 0;
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // 0
 
// **************************** //
 
x = '';
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // ''
 
// **************************** //
 
x = ' ';
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // ' '
 
// **************************** //
 
x = 1;
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // 1
 
// **************************** //
 
x = 2;
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // 2
 
// **************************** //
 
x = true;
x ??= Y; // ici x ne sera pas modifié car il possède une valeur
console.log(x); // true

Fonction privée :
#myFunction(param1, …, paramN) {
…
}
 
Getter privé :
get #myField() {
…
}
 
Setter privé :
set #myField(value) {
…
}

/**
 * This class defines a Person.
 */
class Person {
    #id; // Private field 'id'
    #firstname; // Private field 'firstname'
    #lastname; // Private field 'lastname'
 
    /**
     * Public constructor.
     */
    constructor() {
        // It calls the function setter 'set #uuid(id)'
        // allowing to set the private field 'id'.
        this.#uuid = Person.#generateUUID();
    }
 
    /**
     * Public setter allowing to set a firstname.
     */
    set firstname(firstname) {
        this.#firstname = firstname;
    }
 
    /**
     * Public getter allowing to get a firstname.
     */
    get firstname() {
        return this.#firstname;
    }
 
    /**
     * Public setter allowing to set a lastname.
     */
    set lastname(lastname) {
        this.#lastname = lastname;
    }
 
    /**
     * Public getter allowing to get a lastname.
     */
    get lastname() {
        return this.#lastname;
    }
 
    /**
     * Public getter allowing to get the field 'id' by retrieving it
     * thanks to the private getter 'get #uuid'.
     */
    get id() {
        return this.#uuid;
    }
 
    /**
     * Private setter allowing to set an id.
     */
    set #uuid(id) {
        this.#id = id;
    }

 
 
    /**
     * Private getter allowing to get the current private field id.
     * 
     * @returns the current private field id.
     */
    get #uuid() {
        return this.#id;
    }
 
    /**
     * Public function allowing to return a stringified JSON defining
     * an instance of Person.
     * 
     * @returns a Person as a JSON String.
     */
    toString() {
        return `person: ${JSON.stringify(
            {
                id: this.#id,
                firstName: this.#firstname,
                lastname: this.#lastname
            })}`;
    }
 
    /**
     * Private static function allowing to generate a new stringified UUID.
     * 
     * @returns a stringified UUID.
     */
    static #generateUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (currentChar) => {
            const X_VALUE = (new Date().getTime() + Math.random() * 16) % 16 | 0;
            return (currentChar === 'x' ? X_VALUE : (X_VALUE & 0x3 | 0x8)).toString(16);
        });
    }
 
}
 
const person = new Person();
person.firstname = 'Archibald';
person.lastname = 'Haddock';
 
console.log(person.toString());

let person = {
    firstname: "Thomas",
    lastname: "Sawyer"
};
 
// Caching the person object
const personRefObject = new WeakRef(person);
 
person = null;
 
// Retrieving the person object from the cache
const personFromCache = personRefObject.deref();
 
console.log('The informations about the person coming from the cache are:', personFromCache);

 
let person = { firstname: 'Thomas', lastname: 'Sawyer' };
 
let takenIntoAccountByGarbageCollector = false;
 
// Le registre est créé en passant la fonction callback comme
// paramètre au constructeur.
const registry = new FinalizationRegistry(heldValue => {
    takenIntoAccountByGarbageCollector = true;
    console.log(`The ${heldValue} object has been collected in the 'Garbage Collector'.`)
});
 
// Ensuite, avec la fonction register on inscrit au registre
// les différents objets pour lesquels on veut que la fonction
// de rappel de nettoyage soit appelée. Cette fonction prend en
// argument la valeur courante et une valeur tenue pour celle-ci.
registry.register(person, JSON.stringify(person));
 
// Chaque seconde, on affiche dans la console si l'objet 'person'
// existe toujours et dans le cas où il n'existerait plus et s'il a
// été intercepté avant que le 'Garbage Collector' ne l'ait nettoyée,
// on arrête de logguer son état de vie.
const intervalId = setInterval(() => {
    if (person) {
        console.log('The person already exists:', person);
    } else {
        console.log('The person does not exist anymore.');
 
        if (takenIntoAccountByGarbageCollector) {
            clearInterval(intervalId);
        } else {
            console.log('We are waiting for the \'Garbage Collector\'.');
        }
    }
}, 1000);
 
// Au bout de 3 secondes de traitement on passe à null
// l'objet 'person'.
setTimeout(() => {
    person = null;
}, 3000);