JavaScript


Creative Commons License
This JavaScript tutorial is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License
Preamble
This tutorial is about basic and advanced features of JavaScript. JavaScript is probably the worst programming language ever invented, worse than C! Indeed, JavaScript is not statically typed. This feature prevents early fault compilation at design time, but JavaScript cannot be ignored in the Internet era! From JavaScript 5, it is essential to impose rigorous interpretation rules through the "use strict"; statement that most often appears at the top of a source file.
Headlines
JavaScript file organization requires some form of “ejection” from the inside of HTML files.
Example

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <title>Conception des applications Internet</title>

        <link rel="shortcut icon" href="favicon.ico"/>

        <script src="js/chai.js"></script>
        <script src="js/dat.gui.min.js"></script>

        <!--Internet connection required:-->
        <script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>

        <script src="js/CAI.js"></script>

        <script>
            if (typeof chai === "undefined")
                window.alert("STOP: it won't work because 'chai.min.js' has not been loaded…");
            if (typeof dat === "undefined")
                window.alert("STOP: it won't work because 'dat.gui.min.js' has not been loaded…");
            if (typeof createjs === "undefined")
                window.alert("STOP: it won't work because 'createjs-2015.11.26.min.js' has not been loaded…");
            window.onload = go;
        </script>
    </head>
    <body >
        <canvas id="CAI" width="600" height="400"></canvas>
    </body>
</html>
Content Delivery Network (CDN) for JavaScript is the ability to download libraries from dedicated sites offered by Google, Microsoft, etc. One of the best CDN is https://cdnjs.com
Example (downloading jQuery from Google)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
Loading (in sequence) JavaScript libraries in HTML files may involve a lot of manual management: sequence must respect dependencies, asynchronous loading (for performance) must be explicit using async, etc. RequireJS or Browserify are utilities that avoid such a tricky management.
Example using RequireJS
In this example, we consider a 'UV_mapping_three.js' file as the main program file of a simple Web application . This application reuses the three.js 3D library as a dependency. Only the 'require.js' file is loaded in HTML:
<!-- 'data-main' attribute tells 'require.js' to load 'UV_mapping_three.js' after 'require.js' loads... -->
<!-- *By construction*, 'UV_mapping_three.js' is loaded in an asynchronous way by 'require.js' -->
<!-- Do not be confused by 'async' (see below): it just embodies the asynchronous loading of 'require.js' itself! -->
<script async data-main="./js/UV_mapping_three" src="./js/require.js"></script>
The 'UV_mapping_three.js' must then load what it requires, namely 'three.js'. Note that 'require.js', 'three.js' and 'UV_mapping_three.js' are together stored in a 'js' sub-directory where 'index.html' is located.
requirejs(['three'], function (module) {
    window.THREE = module;
    // While 'three.js' may be used from here, one has however to check that the DOM and/or the full window (images, sounds, videos…) is loaded.  
});
Because of serious permissivity, it is strongly advised to write JavaScript in strict mode so that the interpreter checks the code at run-time (and generates errors viewable in the console navigator if necessary).
Rule(s)
Example
"use strict";
var well_declared_variable = "Strict mode is activated from all statement lines in the rest of this source file!";
ill_declared_variable = 2016; // The absence of 'var' normally raises an error at execution time thanks to the strict mode
Rule(s)
Example
const my_const = "It cannot change!";
my_const = "One says it cannot change!"; // Execution error
if(something) {
    let this_year = 2017; 
} // <- 'this_year' dies right there while 'var' (contrary to 'let') makes the variable living throughout its declaration function
Objects: JavaScript objects are either primitive or, by default, they are created from a prototype that belongs to the Object type. Primitive types are Boolean, Number, String, undefined and Symbol. Another key type is the Function type.
Rule(s)
Example
window.alert(typeof true); // 'boolean'
window.alert(typeof 2016); // 'number'
window.alert(typeof "2016"); // 'string'
var o = Object.create(Object.prototype); // 'var o = {};'
window.alert(typeof o); // 'object'

null and undefined

Rule(s)
Example
var x;
window.alert(typeof x); // 'undefined'
window.alert(typeof null); // 'object'
See also
null and undefined
Symbol type

NaN

Rule(s)
See also
NaN

JavaScript objects are extensible!

var Franck = {};
Object.defineProperty(Franck, "surname", {value: "Barbier", enumerable: true, configurable: true, writable: true});
window.alert(Franck.surname); // 'Barbier' is displayed - One may also access objects' properties as follows: 'Franck["surname"]'

Franck.skill = "JavaScript"; // Dynamic extension
delete Franck.skill; // Dynamic suppression
if ("skill" in Franck === false) window.alert("'Franck.skill' no longer exists…");

Franck.severe = true;
window.alert(JSON.stringify(Franck)); // '{"surname":"Barbier","severe":true}' is displayed

More on objects' attributes and their settings

Object.defineProperty(Franck, "nickname", {value: "Bab", enumerable: true, configurable: false, writable: false});
try {
    Franck.nickname = "Other nickname";
} catch (error) {
    window.alert(error.message); // '"nickname" is read-only' is displayed
}
try {
    delete Franck.nickname;
} catch (error) {
    window.alert(error.message); // 'property "nickname" is non-configurable and can't be deleted' is displayed
}

JavaScript offers predefined objects (with predefinded functions)

Example
window.alert(Math.E); // '2.718281828459045' is displayed
window.alert(Math.ceil(Math.E)); // '3' is displayed

The case of this

The way of dealing with this
Example
Franck.my_array = [null, 0, "ABC"]; // Arrrgggglll, arrays may contain anything!

Franck.my_array_processing = function () {
    for (var i = 0; i < this.my_array.length; i++) {
        this.my_array[i] = this.severe; // Great, 'this' is set to the appropriate "current" object!
    }
};
Franck.my_array_processing();
window.alert(JSON.stringify(Franck)); // '{"surname":"Barbier","nickname":"Bab","severe":true,"my_array":[true,true,true]}' is displayed

Franck.my_array_other_processing = function () {
    this.my_array.forEach(function (element) {
        window.alert("typeof 'this' in 'Franck.my_array_other_processing' : " + typeof this); // 'undefined' is displayed
        element = this.severe; // Arrrgggglll, 'this' is NOT set to the appropriate "current" object: 'TypeError: this is undefined' in the console log!
    }/*, this*/); // You got some trouble just before? Uncomment!
};
Franck.my_array_other_processing();

Using bind

Example
var f = function (element) {
    window.alert(Franck === this); // 'true' is displayed
    element = this.severe;
};
Franck.my_array_other_processing_2nde_version = function () {
    this.my_array.forEach(f.bind(this));
};
Franck.my_array_other_processing_2nde_version();

Control statements

Rule(s)
Example
if(expression) {} // This evaluates to 'true' if 'expression' is not:

        null

        undefined

        NaN

        "" // Empty string

        0

        false
Arrays in JavaScript are, by their very deep flexibility, a core tool to manage collections of elements. Common arrays are instance of the predefined Array constructor while typed arrays have been recently introduced to (mainly) deal with bit streams (i.e., buffers).
var licence_info_UPPA = ["L1", "L2", "L3"];
window.alert(licence_info_UPPA instanceof Array); // 'true' is displayed
window.alert(typeof licence_info_UPPA); // 'object' is displayed
JavaScript functions are powerful tools of the language. They have a first-class status as plain objects. The absence of static typing in JavaScript suppresses any control about functions' arguments and returned objects: their types and number.
Rule(s)
Example
var my_function = function (my_parameter) {
    return ++my_parameter;
};
window.alert(my_function(0)); // '1' is displayed
window.alert(typeof my_function); // 'function' is displayed
window.alert(my_function.constructor === Function); // 'true' is displayed

Anonymous functions

Rule(s)
Example
var f = function (g) { // 'f' is defined
    g();
};
f(function () { // 'f' is called with an anonymous function as parameter
    window.alert("This no-name function plays the role of 'g' as parameter of 'f'");
});

Lambda expressions

Rule(s)
Example
var f = (g) => { // 'f' is defined in an alternative manner using a lambda expression
    g();
};

Meta-functions

Rule(s)
Example
var my_function = function (my_parameter) {
    window.alert(this.surname); // 'Barbier' is displayed since 'Franck' is substituted for 'this' below
    return ++my_parameter;
};
// This is equivalent to 'my_function(0)' above, but the call is more sophisticated:
window.alert("call: " + my_function.call(Franck, 0)); // First arg. plays the role of 'this' inside the function while '0' is substituted for 'my_parameter'
window.alert("apply: " + my_function.apply(Franck, [0])); // First arg. plays the role of 'this' inside the function while '[0]' is a one-element array containing '0' as unique element
Even though JavaScript is not an original OO programming language, design efficiency and rationality strive us to adopt a disciplined approach.
Rule(s)
Example (to be avoided)
var temperature = { // The notion of temperature
    Min: -273.15, // in Celsius
    _value: 0, // in Celsius
    _step: 0.0001,
    asCelsius: function () {
        return _value;
    }
    // Etc.
};
Rule(s)
Example (better, but to be avoided as well)
var Temperature_unit = {
    Celsius: 0,
    Fahrenheit: 1,
    Kelvin: 2
};

function Invalid_temperature_exception(value) {
    this._message = "Invalid temperature";
    this._value = value;
}

var Temperature = function (value, unit) {
    this.Min = -273.15; // in Celsius
    this._value = 0; // in Celsius
    switch (unit) {
        case Temperature_unit.Celsius:
            this._value = value;
            break;
        case Temperature_unit.Fahrenheit:
            this._value = (value - 32.) * 5. / 9.;
            break;
        case Temperature_unit.Kelvin:
            this._value = value + this.Min;
            break;
        default:
            throw "Illegal temperature unit";
    }
    if (this._value < this.Min) {
        throw new Invalid_temperature_exception(this._value);
    }
    this._step = 0.0001;
    this.asCelsius = function () {
        return this._value;
    };
    this.asFahrenheit = function () {
        return 9. / 5. * this._value + 32.;
    };
// Better:
    Object.defineProperty(this, "asKelvin", {value: function () {
                return this._value - this.Min;
            }, enumerable: true, configurable: false, writable: false}
    );
    // Etc.     
};
Rule(s)
Example
Object.defineProperty(Temperature.prototype, "Min", {value: -273.15, enumerable: true, configurable: false, writable: false});

Temperature.prototype.asCelsius = function () {
    return this._value;
};

Temperature.prototype.asFahrenheit = function () {
    return 9. / 5. * this._value + 32.;
};

// Better:
Object.defineProperty(Temperature.prototype, "asKelvin", {value: function () {
        return this._value - this.Min;
    }, enumerable: true, configurable: false, writable: false}
);

// Etc.
Resource(s)
Temperature.js.zip 
Initially, JavaScript has no native support for inheritance and polymorphism. However, as a prototype-based programming language, inheritance and polymorphism can be simulated. One may look at this blog in order to understand how such a simulation may be instrumented.
Rule(s)
Example
var Compte_bancaire = function (id, solde) {
    this._id = id;
    this._solde = solde;
    this._cumul_interets;
};
Compte_bancaire.prototype.id = function () {
    return this._id;
};
Compte_bancaire.prototype.solde = function () {
    return this._solde;
};
Compte_bancaire.prototype.cumul_interets = function () {
    return this._cumul_interets;
};
Compte_bancaire.prototype.mise_a_jour = function (montant) {
    this._solde += montant;
    return this._solde;
};
Compte_bancaire.prototype.taux_interet = function () {
    throw "Undefined function due to abstract nature of 'Compte_bancaire'…";
};
Compte_bancaire.prototype.appliquer_taux_interet = function () {
    this._cumul_interets = this._solde * (1. + (this.taux_interet() / 100.));
};
Compte_bancaire.prototype.compareTo = function (cb) {
    return this._solde > cb._solde ? 1 : this._solde < cb._solde ? -1 : 0;
};

var Compte_cheque = function (id, solde, taux_interet, seuil) {
    Compte_bancaire.call(this, id, solde); // 'super' in Java
    this._taux_interet = taux_interet;
    this._seuil = seuil;
};
Compte_cheque.prototype = Object.create(Compte_bancaire.prototype); // Inheritance link
Compte_cheque.prototype.constructor = Compte_cheque;
Compte_cheque.prototype.taux_interet = function () {
    return this._taux_interet;
};
Compte_cheque.prototype.appliquer_taux_interet = function () {
    if (this._solde > this._seuil) {
        Compte_bancaire.prototype.appliquer_taux_interet.call(this); // 'super' in Java
    }
};
Rule(s)
Example
try {
    var cb = new Compte_bancaire("cb", 100.);
    cb.appliquer_taux_interet(); // This fails since 'Compte_bancaire' is implemented as an abstract class
    window.alert(cb.cumul_interets());
} catch (e) {
    window.alert(e);
}
var cc = new Compte_cheque("cc", 200., 0.02, 100.);
cc.appliquer_taux_interet();
window.alert(cc.cumul_interets());
Note(s)
Resource(s)
CAI.js.zip 
JavaScript 6 natively supports inheritance and polymorphism.
Rule(s)
Example
class Compte_bancaire_JS6 {
    constructor(id, solde) {
        this._id = id;
        this._solde = solde;
        this._cumul_interets;
    }
    static Information() {
        return "Classe générale des comptes bancaires";
    }
    id() {
        return this._id;
    }
    solde() {
        return this._solde;
    }
    cumul_interets() {
        return this._cumul_interets;
    }
    mise_a_jour(montant) {
        this._solde += montant;
        return this._solde;
    }
    taux_interet() {
        throw "Undefined function due to abstract nature of the class...";
    }
    appliquer_taux_interet() {
        this._cumul_interets = this._solde * (1. + (this.taux_interet() / 100.));
    }
    compareTo(cb) {
        return this._solde > cb._solde ? 1 : this._solde < cb._solde ? -1 : 0;
    }
}

class Compte_cheque_JS6 extends Compte_bancaire_JS6 {
    constructor(id, solde, taux_interet, seuil) {
        super(id, solde);
        this._taux_interet = taux_interet;
        this._seuil = seuil;
    }
    static Information() {
        return "Classe des comptes bancaires courants ou \"comptes chèque\" - rémunération à la tête du client !";
    }
    taux_interet() {
        return this._taux_interet;
    }
    appliquer_taux_interet() {
        if (this._solde > this._seuil) {
            super.appliquer_taux_interet();
        }
    }
}
Rule(s)
Example
alert(Compte_bancaire_JS6.Information());
try {
    let cb = new Compte_bancaire_JS6("cb", 100.);
    cb.appliquer_taux_interet(); // This fails since 'Compte_bancaire' is implemented as an abstract class
    window.alert(cb.cumul_interets());
} catch (e) {
    window.alert(e);
}
alert(Compte_cheque_JS6.Information());
let cc = new Compte_cheque_JS6("cc", 200., 0.02, 100.);
cc.appliquer_taux_interet();
window.alert(cc.cumul_interets());
Resource(s)
CAI.js.zip 
The foundation of JavaScript is its event model. In other words, there is no concurrent programming support in JavaScript as multithreading in Java. However, JavaScript is intrinsically concurrent by the possibility of dispatching event occurrences to (developer-defined) handling functions. A lot of event types are available in the JavaScript system. Occurrences of these events (mouse event occurrences for instance) are dispatched by JavaScript for asynchronous processing: events are queued and delivered to handling functions at appropriate moments. The JavaScript event model may be extended through the CustomEvent interface in particular.
Example (mouse events)
var My_controller = function (…) { // 'My_controller' class
    …
    this._my_canvas = document.getElementById("my_canvas");
    …
    this._my_canvas.addEventListener('mousedown', My_controller.prototype.pointerdown.bind(this), false);
    this._my_canvas.addEventListener('mousemove', My_controller.prototype.pointermove.bind(this), false);
    this._my_canvas.addEventListener('mouseover', My_controller.prototype.pointerover.bind(this), false);
    this._my_canvas.addEventListener('mouseup', My_controller.prototype.pointerup.bind(this), false);
    …
};
…
My_controller.prototype.pointerdown = function (mouse_event) {
    mouse_event.preventDefault(); // Default behaviors are canceled
    mouse_event.stopPropagation(); // The event occurrence is processed once and for all
    if (mouse_event.button === 0) { // Mouse left button pressed…
        …
    }
    if (mouse_event.button === 2) { // Mouse right button pressed…
        …
    }        
    …
};
Example (drag&drop events)
var My_controller = function (…) { // 'My_controller' class
    this._file_reader = new FileReader();
    this._file_reader.onerror = function (event) {
        throw("this._file_reader.onerror");
    };
    var file_reader_onload = function (event) {
        var image = new Image();
        image.onload = function () {
           // Image has been loaded after drag&drop
        };
        image.src = event.target.result;
    };
    this._file_reader.onload = file_reader_onload.bind(this);
    …
    this._my_canvas = document.getElementById("my_canvas");
    …
    this._my_canvas.addEventListener('drop', this._drop.bind(this), false);
    …
};
…
My_controller.prototype._drop = function (drag_and_drop_event) {
    drag_and_drop_event.preventDefault(); // Default behaviors are canceled
    drag_and_drop_event.stopPropagation(); // The event occurrence is processed once and for all
    if (drag_and_drop_event.dataTransfer.types && drag_and_drop_event.dataTransfer.types.length > 0 && drag_and_drop_event.dataTransfer.types[0].toLowerCase().includes("file"))
        this._file_reader.readAsDataURL(drag_and_drop_event.dataTransfer.files[0]);
};
Example (developer-defined events)
var Time_management = function (image_name, …) { // 'Time_management' class
    …
    // Event handling policy:
    document.addEventListener('Image_is_ready', this._create_3D_object.bind(this, image_name), false);
    document.addEventListener('3D_object_is_ready', function (custom_event) {
        if (custom_event.detail.name !== this._image_name)
            throw("Abnormal situation…");
        …
    }.bind(this), false);
    …
    this._image = new Image();
    this._image.onload = function () {
        // Image loaded:
        document.dispatchEvent(new Event('Image_is_ready'));
    };
    this._image.src = image_name; // Loading image from here…
};
…
Time_management.prototype._create_3D_object = function (name) {
    if (!(this._image !== undefined && this._image !== null && this._image instanceof Image && this._image.complete))
        throw("Abnormal situation…");
    … // 3D object is constructed from 'this._image' as texture
    document.dispatchEvent(new CustomEvent('3D_object_is_ready', {'detail': {name: name}}));
};
…
Resource(s)
Time_management.js.zip 
Time management is the simple way to perform periodic and/or repetitive tasks. In this scope, window.setInterval (cyclic timer) and window.setTimeout (one-shot timer, see jQuery section) are ready-to-use facilities for time management.
Example
var Time_management = function (…) { // 'Time_management' class
    …
    this._interval_id = null; // 'Time_management' instance attribute
    …
    document.addEventListener('3D_object_is_ready', function () {
        // The timer is launched once the '3D_object_is_ready' event occurrence is received:
        this._interval_id = window.setInterval(this._time_out.bind(this), 5000); // Each 5 sec., the '_time_out' function of the 'Time_management' class is called…
    }.bind(this), false);
    …
};
…
Time_management.prototype._time_out = function () {
    if (…) // Some test
        … // This code is executed each 5 sec. until the timer is cancelled!
    else { // The timer is cancelled:
        window.clearInterval(this._interval_id);
        …
    }
};
Resource(s)
Time_management.js.zip 
Animation is the ability to register a function (e.g., _animate_3D_object in the code below), which is called each time the browser repaints frames. For enabling this mechanism, the devoted facility is window.requestAnimationFrame. Of course, this facility is the key support for rich animation beyond the use of time management facilities. The recommended rate is 60 refreshed frames per sec. (one may note that the original Cinéma used 24 images per sec.).
Example
var Time_management = function (…) { // 'Time_management' class
    …
    this._animation_id = null; 'Time_management' instance attribute
    …
    // The animation is launched once the '3D_object_is_ready' event occurrence is received:
    document.addEventListener('3D_object_is_ready', function (…) {
        …
        this._animation_id = window.requestAnimationFrame(this._animate_3D_object.bind(this));
    }.bind(this), false);
    …
};

Time_management.prototype._animate_3D_object = function (timestamp) {
    if (timestamp !== undefined) { /* first call: 'timestamp === undefined' */
        // One may handle the elapsed time from the first call to '_animate_3D_object'
    }
    … // This code is executed around 60 times per sec. until the animation is cancelled!
    // A new call is queued (mandatory)
    this._animation_id = window.requestAnimationFrame(this._animate_3D_object.bind(this));
};
…
Time_management.prototype._time_out = function () {
    if (…) // Some test
        … // This code is executed each 5 sec. until the timer is cancelled!
    else { // The animation is cancelled:
        …
        window.cancelAnimationFrame(this._animation_id);
        …
    }
};
Resource(s)
Time_management.js.zip 
jQuery is probably the most popular JavaScript library. It mainly offers a graceful way (syntax, etc.) of dealing with the DOM, AJaX and events. jQuery remains a third-party library, i.e., it is not in the core of JavaScript. However, numerous developers use it plus famous extensions like jQuery UI.

jQuery and the DOM

Example (without jQuery)
var canvas = document.createElement("canvas");
canvas.id     = "My canvas";
canvas.style.position = "absolute";
canvas.style.border   = "5px solid red";
document.body.appendChild(canvas);
Example (with jQuery)
var $canvas = $("<canvas>").attr({
    id: "My canvas"
}).css({
    position: "absolute",
    border: "5px solid red"
});
$("body").append($canvas);

var image = new Image();
image.onload = function () {
    $canvas.get(0).width = image.width;
    $canvas.get(0).height = image.height;
    $canvas.get(0).getContext('2d').drawImage(image, 0, 0); // Image is loaded in canvas
};
image.src = "img/Franck.jpg"; // Image load…

Requesting DOM elements with jQuery

The original interest and strength of jQuery is its ability to request any DOM item or item group in a concise query. Here are some examples.

jQuery event programming model

Example (event reception)
$(document).on("Image_just_processed", function_in_charge_of_event_processing); // Event processing policy
function function_in_charge_of_event_processing($event, parameters) { // Event processing
    chai.assert.strictEqual($event.type, "Image_just_processed"); // 'chai.js' nice third-party library for contract-based programming
    swal(parameters.data1 + " just loaded in canvas with width: " + parameters.data2 + " and height: " + parameters.data3); // 'sweetalert.js' nice library
}
Example (event sending)
$(document).trigger("Image_just_processed", {data1: image.src, data2: image.width, data3: image.height});
Note(s)
Example ('on' with multiple event types)
$(document).on("e1_event e2_event", e1_e2_handling_function); // Event processing policy
Resource(s)
jQuery.js.zip 

jQuery Deferred Object

The notion of Deferred Object in jQuery is a powerful event programming model that goes beyond the original JavaScript event programming model and its implementation in jQuery.
Example
var $event_1 = $.Deferred();
var $event_2 = $.Deferred();
var $event_3 = $.Deferred();

var to_do = function (event_1_name, event_2_name, event_3_name) { // Event handling
    swal("State of " + event_1_name + ": " + $event_1.state() + '\n' +
        "State of " + event_2_name + ": " + $event_2.state() + '\n' +
        "State of " + (event_3_name === undefined ? "-no parameter set for event_3_name- " : event_3_name + ": ") + $event_3.state()); // 'sweetalert.js' nice library
};
// Removing comments leads to have no triggering for 'to_do' since 'event_3' is rejected (see below)…
$.when($event_1, $event_2/*, $event_3*/).done(to_do); // Event handling policy

(function () {
    window.setTimeout(sending_event_1, 3000); // One shot only
    function sending_event_1() {
        console.log("Waiting 3 sec. before sending " + "event_1");
        $event_1.resolve("event_1");
    }
})();

(function () {
    window.setTimeout(sending_event_2, 2000); // One shot only
    function sending_event_2() {
        console.log("Waiting 2 sec. before sending " + "event_2");
        $event_2.resolve("event_2");
    }
})();

(function () {
    window.setTimeout(rejecting_event_3, 1000); // One shot only
    function rejecting_event_3() {
        console.log("Waiting 1 sec. before rejecting " + "event_3");
        $event_3.reject("event_3");
    }
})();
Resource(s)
jQuery_Deferred_Object.js.zip 
Promises aim at replacing the notions of 'Deferred Object' and 'Promise' in jQuery. However, the way of using Promises in native JavaScript is fairly different from that of jQuery.
Example (marking the DOM ready as a promise and testing it later on)
let DOM_ready = null;
Object.defineProperty(window, "DOM_ready", {value: new Promise(function_launched_when_DOM_ready => {
    DOM_ready = function_launched_when_DOM_ready;
}), enumerable: false, configurable: false, writable: false});
document.onreadystatechange = DOM_ready;
…
// In many other places, one may check whether the DOM is ready:
window.DOM_ready.then(value => {// Anonymous function as parameter of 'then'. This function has itself 'value' as parameter...
    document.body.innerWidth = 800;
    document.body.innerHeight = 600;
    // Etc.
});
Example (testing that both the DOM is ready and the full window (images, sounds, videos…) is loaded)
let Window_loaded = null;
Object.defineProperty(window, "Window_loaded", {value: new Promise(function_launched_when_Window_loaded => {
    Window_loaded = function_launched_when_Window_loaded;
}), enumerable: false, configurable: false, writable: false});
window.addEventListener('load', Window_loaded);
// In many other places, one may check whether both the DOM is ready and the full window (images, sounds, videos…) is loaded:
Promise.all([window.DOM_ready, window.Window_loaded]).then(value => { // 'value' is an array of results provided by 'window.DOM_ready' and 'window.Window_loaded'
    alert('Everything is now ready for the Web!');
});
Resource(s)
Promises_illustration.js.zip 
Web Services are server-side programs accessible throughout the Web. By appropriate calls in JavaScript, one is able to get many data and to reduce computations on the client side.
Rule(s)
Example
Note(s)
Resource(s)
Web_Services.js.zip 
WebSockets is a technology that promotes bi-directional full-duplex communication between (not exclusively) browsers and WebSockets servers. Deploying servers for homemade business relies on products like Node.js or libraries like Tyrus in Java. For testing purposes, it is also possible to get access to running servers on the Web like the “echo” WebSockets server at this place: https://www.websocket.org/echo.html. Otherwise, the general way of dealing with WebSockets in Javascript is described here.
Web Workers is a support for dealing with a kind of multithreading. More precisely, some JavaScript code may run outside the browser so that this code lightens the load on the browser. Web Workers mainly consist in facilities to assign background tasks from a browser to a given Web worker that runs in parallel with the said browser.
Rule(s)
Example ("main" thread in the browser)
/*
 * Web_Workers_main.js
 */

"use strict";

function main() {

    var $canvas = $("#My_canvas").get(0); // jQuery access to DOM canvas elem. with 'My_canvas' as id.
    var image = new Image();
    var worker = new Worker("js/Web_Workers_parallel.js"); // Behind the browser stage, this "parallel" code is that of the worker…

    worker.addEventListener("message", response_from_process_image_by_worker); // Subscription about worker's response
    function response_from_process_image_by_worker(message) { // Handler of worker's response
        swal({// Use of the nice 'sweetalert' JS library!
            title: "Web Workers",
            text: "Worker just terminated image processing… Show it?",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#DD6B55",
            confirmButtonText: "Yes!",
            closeOnConfirm: true
        }, function () {
            $canvas.getContext('2d').putImageData(message.data, 0, 0); // Reload of processed image…
        });
        worker.terminate(); // Worker is no longer used, 'close' optional statement
    }

    $(document).on("go!", process_image_by_worker); // Wait for image availability
    function process_image_by_worker() { // Handler of image availability
        if (window.Worker) { // Test if the browser supports the Web Workers technology
            // Instance of 'ImageData' must be sent since it is processable by the new HTML5 structured clone algorithm:
            worker.postMessage($canvas.getContext('2d').getImageData(0, 0, $canvas.width, $canvas.height));
        }
    }

    image.onload = function () {
        $canvas.width = image.width;
        $canvas.height = image.height;
        $canvas.getContext('2d').drawImage(image, 0, 0); // Image is loaded in canvas
        $(document).trigger("go!"); // Image availability: event triggering in jQuery
    };
    image.src = "img/Image.jpg"; // Image load…
}
Example ("parallel" thread outside the browser)
/*
 * Web_Workers_parallel.js
 */

"use strict";

self.importScripts("chai.js"); // Reused libraries require local-scope load…

function process(image_data) {
    var buffer = new Uint32Array(image_data.data.buffer);
    for (var pixel_number = 0; pixel_number < buffer.length; pixel_number++) {
        var alpha = buffer[pixel_number] >>> 24; // Most left byte
        var blue = (buffer[pixel_number] & 0x00FF0000) >> 16;
        var green = (buffer[pixel_number] & 0x0000FF00) >> 8;
        var red = buffer[pixel_number] & 0x000000FF; // Most right byte
// Simplistic image processing, please improve:
        blue = ~blue;
        green = ~green;
        // red = ~red;
        buffer[pixel_number] = alpha | (blue << 16) | (green << 8) | red;
    }
}

onmessage = function (message) { // Message from 'main' thread, i.e., 'worker.postMessage($canvas.getContext('2d').getImageData(0, 0, $canvas.width, $canvas.height));', is received…
    chai.assert.isTrue(message.data instanceof ImageData); // Check received data
    process(message.data);
    postMessage(message.data); // Response from worker to 'main' thread…
};
Resource(s)
Web_Workers.js.zip 
JavaScript supports rich APIs for multimedia management (image, video, sound…) in general and gaming in particular.

Shooting: WebRTC

WebRTC allows the direct access to input device, namely webcams and microphones. For example, a basic program of photo capture can be found here.
Rule(s)
Example (finding available devices)
window.navigator.mediaDevices.enumerateDevices().then(function (devices) { // 'window.navigator.mediaDevices !== undefined' -> WebRTC available!
    devices.forEach(function (device) {
        alert(device.kind + ": " + device.label + " id = " + device.deviceId);
    });
})
.catch(function (error) {
    console.log(error.name + ": " + error.message);
});

Dubbing: Web Audio API

Full screen and pointer lock