Développer en JavaScript

ECMA Script (JavaScript)

JavaScript is one of the 3 languages all web developers must learn:

  * HTML to define the content of web pages
  * CSS to specify the layout of web pages
  * JavaScript to program the behavior of web pages

This tutorial is about JavaScript, and how JavaScript works with HTML and CSS.


===== Change Properties =====
<code>
<!DOCTYPE html>
<html>
<body>

<h1>What Can JavaScript Do?</h1>

<p id="demo" style="font-size:55px; font-family:arial;">JavaScript can change the style of an HTML element.</p>

<button type="button" onclick="document.getElementById('demo').style.fontSize='15px'">Click Me!</button>


</body>
</html> 
</code>

===== Position =====

JavaScript can be placed in the <body> and the <head> sections of an HTML page.
In HTML, JavaScript code must be inserted between <script> and </script> tags.

<code>
 <script>
document.getElementById("demo").innerHTML = "My First JavaScript";
</script> 
</code>


JavaScript

====Syntaxe====
  * JavaScript statements are separated by semicolons.
  * All JavaScript identifiers are case sensitive. 
  * The first character must be a letter, an underscore (_), or a dollar sign ($) and subsequent characters may be letters, digits, underscores, or dollar signs.
  * Numbers are not allowed as the first character.

===Conventions===
==Variable Names==
  * camelCase for identifier names (variables and functions).
  * All names start with a letter.
  
==Spaces Around Operators==
Always put spaces around operators ( = + - * / ), and after commas:

====getElementById====
document.getElementById("demo").innerHTML = "Hello JavaScript";

JavaScript can be placed in the <body> and the <head> sections of an HTML page. 
In HTML, JavaScript code must be inserted between <script> and </script> tags.

Le code suivant est éxécuté lorsque l'on clique sur le bouton.

<code>
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
    document.getElementById("demo").innerHTML = "Paragraph changed.";
}
</script>
</head>

<body>
<h1>My Web Page</h1>

<p id="demo">A Paragraph</p>

<button type="button" onclick="myFunction()">Try it</button>

</body>
</html>
</code>

Le code JS peut également être stocké dans un fichier externe et référéncé de la sorte :
<!DOCTYPE html>
<html>
<body>
<script src="myScript.js"></script>
</body>
</html>
====JavaScript Display Possibilities====
JavaScript can "display" data in different ways:
  •  Writing into an alert box, using window.alert().
  •  Writing into the HTML output using document.write().
  •  Writing into an HTML element, using innerHTML.
  •  Writing into the browser console, using console.log().

====Variables====
JavaScript uses the var keyword to declare variables, and an equal sign is used to assign values to variables.

You can declare many variables in one statement just separate the variables by comma:

var person = "John Doe", carName = "Volvo", price = 200;

====Commentaires====
Code after double slashes / / or between / * and * / is treated as a comment.

====JavaScript Keywords====
Keyword Description
break Terminates a switch or a loop
continue Jumps out of a loop and starts at the top
debugger Stops the execution of JavaScript, and calls (if available) the debugging function
do ... while Executes a block of statements, and repeats the block, while a condition is true
for Marks a block of statements to be executed, as long as a condition is true
function Declares a function
if ... else Marks a block of statements to be executed, depending on a condition
return Exits a function
switch Marks a block of statements to be executed, depending on different cases
try ... catch Implements error handling to a block of statements
var Declares a variable

====JavaScript Arithmetic Operators====
Arithmetic operators are used to perform arithmetic on numbers (literals or variables).

^Operator^Description^
|+|Addition|
|-|Subtraction|
|*|Multiplication|
|/|Division|
|%|Modulus|
|+ +|Increment|
|--|Decrement|

====JavaScript Assignment Operators====
Assignment operators assign values to JavaScript variables.

Operator Example Same As
= x = y x = y
+= x += y x = x + y
-= x -= y x = x - y
*= x *= y x = x * y
/= x /= y x = x / y
%= x %= y x = x % y

====JavaScript Comparison and Logical Operators====
Operator Description
= = equal to
= = = equal value and equal type
!= not equal
!= = not equal value or not equal type
> greater than
< less than
>= greater than or equal to
<= less than or equal to
? ternary operator

====JavaScript Type Operators====

===typeof Operator===
You can use the typeof operator to find the data type of a JavaScript variable.

Example
typeof "John"                 // Returns "string" 
typeof 3.14                   // Returns "number"
typeof NaN                    // Returns "number"
typeof false                  // Returns "boolean"
typeof [1,2,3,4]              // Returns "object"
typeof {name:'John', age:34}  // Returns "object"
typeof new Date()             // Returns "object"
typeof function () {}         // Returns "function"
typeof myCar                  // Returns "undefined" *
typeof null                   // Returns "object"

Please observe:

The data type of NaN is number
The data type of an array is object
The data type of a date is object
The data type of null is object
The data type of an undefined variable is undefined *
The data type of a variable that has not been assigned a value is also undefined *
You cannot use typeof to determine if a JavaScript object is an array (or a date).


instanceof Returns true if an object is an instance of an object type


===The constructor Property===
The constructor property returns the constructor function for all JavaScript variables.

You can check the constructor property to find out if an object is an Array (contains the word "Array"), if an object is a Date (contains the word "Date"):


====JavaScript Function Syntax ====
A JavaScript function is defined with the function keyword, followed by a name, followed by parentheses () or parameters list (parameter1, parameter2, ...).

Function names can contain letters, digits, underscores, and dollar signs (same rules as variables).

The code to be executed, by the function, is placed inside curly brackets: {}

function name(parameter1, parameter2, parameter3) {
    code to be executed
}
Function arguments are the real values received by the function when it is invoked; inside the function, the arguments (the parameters) behave as local variables. If a function is called with a missing argument, the value of the missing argument is set to undefined.

Accessing a function without () will return the function definition.


====Common HTML Events====
Here is a list of some common HTML events:

Event Description
onchange An HTML element has been changed
onclick The user clicks an HTML element
onmouseover The user moves the mouse over an HTML element
onmouseout The user moves the mouse away from an HTML element
onkeydown The user pushes a keyboard key
onload The browser has finished loading the page

====String Functions====
  * lastIndexOf("locate")
  * str.lastIndexOf("locate")
  * str.search("locate");
  * toUpperCase()
  * toLowerCase()
  
===Extracting String Parts===
There are 3 methods for extracting a part of a string:

==slice(start, end)==
slice() extracts a part of a string and returns the extracted part in a new string.

The method takes 2 parameters: the starting index (position), and the ending index (position).
If a parameter is negative, the position is counted from the end of the string.
If you omit the second parameter, the method will slice out the rest of the string.

==substring(start, end)==

==substr(start, length)==
substr() is similar to slice().

The difference is that the second parameter specifies the length of the extracted part.
If the first parameter is negative, the position counts from the end of the string.

The second parameter can not be negative, because it defines the length.
If you omit the second parameter, substr() will slice out the rest of the string.

===Replacing String Content===
The replace() method replaces a specified value with another value in a string:

The replace() method can also take a regular expression as the search value.

By default, the replace() function replaces only the first match. To replace all matches, use a regular expression with a g flag (for global match):
Example
  str = "Please visit Microsoft!";
  var n = str.replace(/Microsoft/g,"W3Schools");
===Character Extraction===
==The charAt() Method==
The charAt() method returns the character at a specified index (position) in a string:

  var str = "HELLO WORLD";
  str.charAt(0);            // returns H

==charCodeAt() Method==
The charCodeAt() method returns the unicode of the character at a specified index in a string:

  var str = "HELLO WORLD";
  str.charCodeAt(0);         // returns 72

==Converting a String to an Array==
A string can be converted to an array with the split() method:

<code>
var txt = "a,b,c,d,e";   // String
txt.split(",");          // Split on commas
txt.split(" ");          // Split on spaces
txt.split("|");          // Split on pipe
</code>

If the separator is "", the returned array will be an array of single characters:

Converting Variables to Numbers

There are 3 JavaScript methods that can be used to convert variables to numbers:

==The Number() method==
==The parseInt() method==
parseInt() parses a string and returns a whole number. Spaces are allowed. Only the first number is returned:

==The parseFloat() method==

These methods are not number methods, but global JavaScript methods.

====Number Properties====
Property Description
MAX_VALUE Returns the largest number possible in JavaScript
MIN_VALUE Returns the smallest number possible in JavaScript
NEGATIVE_INFINITY Represents negative infinity (returned on overflow)
NaN Represents a "Not-a-Number" value
POSITIVE_INFINITY Represents infinity (returned on overflow)


Method Description
toExponential() Returns a string, with a number rounded and written using exponential notation.
toFixed() Returns a string, with a number rounded and written with a specified number of decimals.
toPrecision() Returns a string, with a number written with a specified length

Method Description
parseFloat() Parses a string and returns a floating point number
parseInt() Parses a string and returns an integer

====Math Object Methods====
Method Description
abs(x) Returns the absolute value of x
acos(x) Returns the arccosine of x, in radians
asin(x) Returns the arcsine of x, in radians
atan(x) Returns the arctangent of x as a numeric value between -PI/2 and PI/2 radians
atan2(y,x) Returns the arctangent of the quotient of its arguments
ceil(x) Returns the value of x rounded up to its nearest integer
cos(x) Returns the cosine of x (x is in radians)
exp(x) Returns the value of Ex
floor(x) Returns the value of x rounded down to its nearest integer
log(x) Returns the natural logarithm (base E) of x
max(x,y,z,...,n) Returns the number with the highest value
min(x,y,z,...,n) Returns the number with the lowest value
pow(x,y) Returns the value of x to the power of y
random() Returns a random number between 0 and 1
round(x) Returns the value of x rounded to its nearest integer
sin(x) Returns the sine of x (x is in radians)
sqrt(x) Returns the square root of x
tan(x) Returns the tangent of an angle

====Date Objects and Methods====
In JavaScript : 
  * the first day of the week (0) means "Sunday", even if some countries in the world consider the first day of the week to be "Monday"
  * months from 0 to 11. January is 0. December is 11.

===JavaScript Date Input===
There are generally 4 types of JavaScript date input formats:

Type Example
ISO Date "2015-03-25" (The International Standard)
Short Date "03/25/2015" or "2015/03/25"
Long Date "Mar 25 2015" or "25 Mar 2015"
Full Date "Wednesday March 25 2015"

var d = new Date("2015-03-25");

===Date Get Methods===
Get methods are used for getting a part of a date. Here are the most common (alphabetically):

Method Description
getDate() Get the day as a number (1-31)
getDay() Get the weekday as a number (0-6)
getFullYear() Get the four digit year (yyyy)
getHours() Get the hour (0-23)
getMilliseconds() Get the milliseconds (0-999)
getMinutes() Get the minutes (0-59)
getMonth() Get the month (0-11)
getSeconds() Get the seconds (0-59)
getTime() Get the time (milliseconds since January 1, 1970)

===Date Set Methods===
Set methods are used for setting a part of a date. Here are the most common (alphabetically):

Method Description
setDate() Set the day as a number (1-31)
setFullYear() Set the year (optionally month and day)
setHours() Set the hour (0-23)
setMilliseconds() Set the milliseconds (0-999)
setMinutes() Set the minutes (0-59)
setMonth() Set the month (0-11)
setSeconds() Set the seconds (0-59)
setTime() Set the time (milliseconds since January 1, 1970)

Arrays

Array Elements Can Be Objects
JavaScript variables can be objects. Arrays are special kinds of objects.

Because of this, you can have variables of different types in the same Array.

You can have objects in an Array. You can have functions in an Array. You can have arrays in an Array:

  myArray[0] = Date.now;
  myArray[1] = myFunction;
  myArray[2] = myCars;

===Array Properties and Methods===
The real strength of JavaScript arrays are the built-in array properties and methods:

Examples
var x = cars.length;   // The length property returns the number of elements
var y = cars.sort();   // The sort() method sorts arrays

==Looping Array Elements==
The best way to loop through an array, is using a "for" loop:

<code>
var fruits, text, fLen, i;

fruits = ["Banana", "Orange", "Apple", "Mango"];
fLen = fruits.length;
text = "<ul>";
for (i = 0; i < fLen; i++) {
    text += "<li>" + fruits[i] + "</li>";
}
</code>

==Array Manipulation==
=Add To Array with push method=

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  fruits.push("Lemon");       

=Add To Array with length method=

  fruits[fruits.length] = "Lemon";     // adds a new element (Lemon) to fruits

=Display all items=
  The join() method joins all array elements into a string, it behaves just like toString(), but in addition you can specify the separator:

  var fruits = ["Banana", "Orange","Apple", "Mango"];
  document.getElementById("demo").innerHTML = fruits.join(" * ");

=Pop from Array=
The pop() method removes the last element from an array:

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  fruits.pop();              // Removes the last element ("Mango") from fruits

==Identify Array Types==
To solve this problem ECMAScript 5 defines a new method Array.isArray():

=Pushing=
The push() method adds a new element to an array (at the end). The push() method returns the new array length.

=Shifting Elements=
Shifting is equivalent to popping, working on the first element instead of the last.

The shift() method removes the first array element and "shifts" all other elements to a lower index, and returns the string that was "shifted out".

=Unshifting Elements=
The unshift() method adds a new element to an array (at the beginning), "unshifts" older elements, returns the new array length.

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  fruits.unshift("Lemon");    // Adds a new element "Lemon" to fruits

=Deleting Elements=
Since JavaScript arrays are objects, elements can be deleted by using the JavaScript operator delete:

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  delete fruits[0];           // Changes the first element in fruits to undefined

Using delete may leave undefined holes in the array. Use pop() or shift() instead.

=Using Splice to Add Elements to an Array=
The splice() method can be used to add new items to an array:

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  fruits.splice(2, 0, "Lemon", "Kiwi");

The first parameter (2) defines the position where new elements should be added (spliced in).
The second parameter (0) defines how many elements should be removed.

The rest of the parameters ("Lemon" , "Kiwi") define the new elements to be added.

=Using splice() to Remove Elements to an Array=
With clever parameter setting, you can use splice() to remove elements without leaving "holes" in the array:

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  fruits.splice(0, 1);        // Removes the first element of fruits

The first parameter (0) defines the position where new elements should be added (spliced in).
The second parameter (1) defines how many elements should be removed.
The rest of the parameters are omitted. No new elements will be added.

=Joining Arrays=
The concat() method creates a new array by concatenating two arrays:

  var myGirls = ["Cecilie", "Lone"];
  var myBoys = ["Emil", "Tobias","Linus"];
  var myChildren = myGirls.concat(myBoys);     // Concatenates (joins) myGirls and myBoys

=Using Slice to Get a SubArray of an Array=
The slice() method slices out a piece of an array into a new array.

This example slices out a part of an array starting from array element 1 ("Orange"):

  var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
  var citrus = fruits.slice(1);

The slice() method creates a new array. It does not remove any elements from the source array.
The slice() method can take two arguments like slice(1,3).
The method then selects elements from the start argument, and up to (but not including) the end argument.

===Sorting an Array===
  * sort()
  * reverse()
  
This works well for strings ("Apple" comes before "Banana").

However, if numbers are sorted as strings, "25" is bigger than "100", because "2" is bigger than "1".

Because of this, the sort() method will produce incorrect result when sorting numbers.

You can fix this by providing a compare function:

Example
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});


Sorting Object Arrays
JavaScript arrays often contain objects:

var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];

cars.sort(function(a, b){return a.year - b.year});

====Conditional Statements====
===if/else/else if==
if (time < 10) {
    greeting = "Good morning";
} else if (time < 20) {
    greeting = "Good day";
} else {
    greeting = "Good evening";
}
</code>
===switch===
The switch statements use strict comparison.

<code>
case 1:
    case 2:
    case 3:
    default: 
        text = "Looking forward to the Weekend";
        break; 
    case 4:
    case 5:
       text = "Soon it is Weekend";
        break; 
    case 0:
    case 6:
       text = "It is Weekend";
</code>

Loops

===for===
The standard way :
  for (i = 0; i < 5; i++) {
      text += "The number is " + i + "<br>";
  }
You can initiate many values in statement 1 (separated by comma):
<code>
for (i = 0, len = cars.length, text = ""; i < len; i++) { 
    text += cars[i] + "<br>";
}
</code>
And you can omit statement 1 (like when your values are set before the loop starts):

<code>
var i = 2;
var len = cars.length;
var text = "";
for (; i < len; i++) { 
    text += cars[i] + "<br>";
}
</code>

Often statement 2 is used to evaluate the condition of the initial variable.

This is not always the case, JavaScript doesn't care. Statement 2 is also optional.

If statement 2 returns true, the loop will start over again, if it returns false, the loop will end.


Often statement 3 increments the value of the initial variable.

This is not always the case, JavaScript doesn't care, and statement 3 is optional.

Statement 3 can do anything like negative increment (i--), positive increment (i = i + 15), or anything else.

Statement 3 can also be omitted (like when you increment your values inside the loop):

===for/in===
The JavaScript for/in statement loops through the properties of an object:

<code>
var person = {fname:"John", lname:"Doe", age:25}; 

var text = "";
var x;
for (x in person) {
    text += person[x];
}
</code>
===While Loop===
The while loop loops through a block of code as long as a specified condition is true.

<code>
while (i < 10) {
    text += "The number is " + i;
    i++;
}
</code>

===Do/While Loop===
The do/while loop is a variant of the while loop. This loop will execute the code block once, before checking if the condition is true, then it will repeat the loop as long as the condition is true.

do {
    text += "The number is " + i;
    i++;
}
while (i < 10);

===continue===
The Continue Statement
The continue statement breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop.

This example skips the value of 3:

<code>
for (i = 0; i < 10; i++) {
    if (i === 3) { continue; }
    text += "The number is " + i + "<br>";
}
</code>

===Labels===
To label JavaScript statements you precede the statements with a label name and a colon:

With a label reference, the break statement can be used to jump out of any code block:

<code>
var cars = ["BMW", "Volvo", "Saab", "Ford"];
list: {
    text += cars[0] + "<br>"; 
    text += cars[1] + "<br>"; 
    text += cars[2] + "<br>"; 
    break list;
    text += cars[3] + "<br>"; 
    text += cars[4] + "<br>"; 
    text += cars[5] + "<br>"; 
}
</code>

====Regular Expression====
A regular expression is a sequence of characters that forms a search pattern.

Syntax
  /pattern/modifiers;

Example
  var patt = /w3schools/i;
  Example explained:

/w3schools/i  is a regular expression.

w3schools  is a pattern (to be used in a search).

i  is a modifier (modifies the search to be case-insensitive).


In JavaScript, regular expressions are often used with the two string methods: search() and replace().

  var str = "Visit Microsoft!";
  var res = str.replace(/microsoft/i, "W3Schools");
  
===Regular Expression Patterns===
Brackets are used to find a range of characters:

Expression Description
[abc] Find any of the characters between the brackets
[0-9] Find any of the digits between the brackets
(x|y) Find any of the alternatives separated with |

Metacharacters are characters with a special meaning:

Metacharacter Description
\d Find a digit
\s Find a whitespace character
\b Find a match at the beginning or at the end of a word
\uxxxx Find the Unicode character specified by the hexadecimal number xxxx
Quantifiers define quantities:

Quantifier Description
n+ Matches any string that contains at least one n
n* Matches any string that contains zero or more occurrences of n
n? Matches any string that contains zero or one occurrences of n

===test() method===
The test() method is a RegExp expression method.

It searches a string for a pattern, and returns true or false, depending on the result.

The following example searches a string for the character "e":
  var patt = /e/;
  patt.test("The best things in life are free!");
Since there is an "e" in the string, the output of the code above will be:
  true
You don't have to put the regular expression in a variable first. The two lines above can be shortened to one:
  /e/.test("The best things in life are free!");
  
===exec() Method===
The exec() method is a RegExp expression method. It searches a string for a specified pattern, and returns the found text. If no match is found, it returns null.

The following example searches a string for the character "e":

Example 1
/e/.exec("The best things in life are free!");
Since there is an "e" in the string, the output of the code above will be:
  e

=====JavaScript Errors - Throw and Try to Catch=====
  * The try statement lets you test a block of code for errors.
  * The catch statement lets you handle the error.
  * The throw statement lets you create custom errors.
  * The finally statement lets you execute code, after try and catch, regardless of the result.

<code>
function myFunction() {
    var message, x;
    message = document.getElementById("message");
    message.innerHTML = "";
    x = document.getElementById("demo").value;
    try { 
        if(x == "") throw "is empty";
        if(isNaN(x)) throw "is not a number";
        x = Number(x);
        if(x > 10) throw "is too high";
        if(x < 5) throw "is too low";
    }
    catch(err) {
        message.innerHTML = "Error: " + err + ".";
    }
    finally {
        document.getElementById("demo").value = "";
    }
}
</code>

Debugging

===The debugger Keyword===
The debugger keyword stops the execution of JavaScript, and calls (if available) the debugging function. This has the same function as setting a breakpoint in the debugger. If no debugging is available, the debugger statement has no effect.

With the debugger turned on, this code will stop executing before it executes the third line.

  var x = 15 * 5;
  debugger;
  document.getElementbyId("demo").innerHTML = x;
  
=====Practices=====
===The "use strict" Directive===
The "use strict;" directive is new in JavaScript 1.8.5 (ECMAScript version 5).

With strict mode, you can not, for example, use undeclared variables.

Strict mode is supported in:
IE from version 10. Firefox from version 4.
Chrome from version 13. Safari from version 5.1.
Opera from version 12.

Strict mode changes previously accepted "bad syntax" into real errors.

As an example, in normal JavaScript, mistyping a variable name creates a new global variable. In strict mode, this will throw an error, making it impossible to accidentally create a global variable.

In normal JavaScript, a developer will not receive any error feedback assigning values to non-writable properties.

In strict mode, any assignment to a non-writable property, a getter-only property, a non-existing property, a non-existing variable, or a non-existing object, will throw an error.


===Not Allowed in Strict Mode===
  * Using a variable, without declaring it, is not allowed:
  * Deleting a variable (or object) is not allowed : var x = 3.14; delete x;                // This will cause an error
  * Deleting a function is not allowed : function x(p1, p2) {};  delete x;                // This will cause an error 
  * Duplicating a parameter name is not allowed: function x(p1, p1) {};   // This will cause an error
  * Octal numeric literals are not allowed: var x = 010;             // This will cause an error
  * Escape characters are not allowed: var x = \010;            // This will cause an error
  * Writing to a read-only property is not allowed:  "use strict"; var obj = {}; Object.defineProperty(obj, "x", {value:0, writable:false}); obj.x = 3.14;            // This will cause an error
  * Writing to a get-only property is not allowed:  "use strict"; var obj = {get x() {return 0} }; obj.x = 3.14;            // This will cause an error
  * Deleting an undeletable property is not allowed: "use strict"; delete Object.prototype; // This will cause an error
  * The string "eval" cannot be used as a variable: "use strict";var eval = 3.14;         // This will cause an error
  * The string "arguments" cannot be used as a variable:  "use strict"; var arguments = 3.14;    // This will cause an error
  * The with statement is not allowed: "use strict";with (Math){x = cos(2)}; // This will cause an error
  

JavaScript and Java are completely different languages, both in concept and design.
JavaScript was invented by Brendan Eich in 1995, and became an ECMA standard in 1997.
 

ECMAScript a été créé pour standardiser JavaScript, et ES6 est la 6ème version of ECMAScript. Publié en 2015, il est également connu sous le nom de ECMAScript 2015.

Why Should I Learn ES6? https://www.w3schools.com/react/react_es6.asp
React uses ES6

Variables

En JavaScript, il y a trois types primitifs principaux :

  • number (nombre) ;
  • string (chaîne de caractères) ;
  • boolean (valeur logique).

Et trois autres types de données primitifs : null, undefined et symbol.

JavaScript est un langage dit à types dynamiques et à typage faible. Cela signifie que vous pouvez initialiser une variable en tant que nombre, puis la réaffecter comme chaîne, ou tout autre type de variable.  Un bloc de code est délimité par {}.

var

Avant l'arrivée de ES6, var était le seul moyen de déclarer une variable.

Scope

  • est global quand la déclaratation a lieu en dehors d'une fonction
  • est scopé à la fonction scoped quand la déclaration se trouve dans le corps d'une fonction

Les variables déclarées avec var peuvent être re-declarée and mises à jour.

Il n'y a aucun problème à écrire :

var myVariable = "string"
var myVariable = 3

let

Depuis l'arrivée d'ES6,  let est à présent la manière privilégiée pour déclarer une variable.

Une variable déclarée avec let est scopée au bloc.  Comme avec var,  une variable declarée avec let peut etre mise à jour dans son scope. A la différence de var, une variable délcarée avec let ne peut pas être redéclarée dans un même scope.

Comme avec var, les variables déclarées avec let sont posées sur la pile. A la différence de var qui initialislise une variable comme undefined, les variables déclarées avec let ne sont pas initialisées et leur usage sans initialisation provoquera une "Reference Error".

const

Variables declared with the const maintain constant values.  It does not define a constant value. It defines a constant reference to a value.

const declarations are block scoped

const cannot be updated or re-declared

This means that the value of a variable declared with const remains the same within its scope. It cannot be updated or re-declared. So if we declare a variable with const, we can neither do this:

Every const declaration, therefore, must be initialized at the time of declaration.

This behavior is somehow different when it comes to objects declared with const. While a const object cannot be updated, the properties of this objects can be updated. Therefore, if we declare a const object as this:

const greeting = {
message: "say Hi",
times: 4
}

we can update message but not greeting.

var variables can be updated and re-declared within its scope; let variables can be updated but not re-declared; const variables can neither be updated nor re-declared.

Because of this you can NOT:
  • Reassign a constant value
  • Reassign a constant array
  • Reassign a constant object
But you CAN:
  • Change the elements of constant array
  • Change the properties of constant object

typeof

To find the type of the box variable at runtime, you use the typeof operator:

let nft;
console.log(typeof(nft)); // undefined

nft = "Hello";
console.log(typeof(nft)); // string

nft = 100;
console.log(typeof(nft)); // number

Valeur vs Référence

Les types primitifs tels que les nombres, les valeurs logiques et les chaînes sont passés par valeur. Ceci signifie que quand vous faites quelque chose comme :

let balanceExistante = 20;

let nouvelleBalance = balanceExistante; // 20

... c'est la valeur 20 qui est copiée dans la nouvelle variable (nouvelleBalance), et aucun lien n'est maintenu entre les deux variables.

Ce n'est pas le cas avec les objets et tableaux, qui sont passés par référence. Si vous n'y prenez pas garde, cela peut conduire à des comportements inattendus. 

https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

Tableaux

Pour créer un tableau vide et l'enregistrer dans une variable, utilisez une paire de crochets :
let artistes = [];

Vous pouvez aussi créer un tableau rempli en plaçant les éléments voulus à l'intérieur de ces crochets :
let artistes = ["NFT Kate", "Token Simon", "Will Ian"];

Vous pouvez ensuite accéder aux éléments de ce tableau par leur indice en base 0 :

let artisteUn = artistes[0]; // "NFT Kate"
let artisteDeux = artistes[2]; // "Will Ian"
let artisteInconnu = artistes[12] // undefined

Longueur d'un Tableau
let howManyGuests = guests.length; // 3

Ajouter un élément à la fin d'un tableau avec la méthode push :
artistes.push("Cyber Alice"); // ajoute "Cyber Alice" en fin de tableau

Ajouter un élément au début du tableau plutôt qu'à la fin, utilisez la méthode unshift :
artistes.unshift("King Botasa"); // "King Botasa" est ajouté au début du tableau

Supprimer le dernier élément d'un tableau avec la méthode pop :
artistes.pop(); // supprimer le dernier élément du tableau

Objets JavaScript

Les objets JavaScript sont écrits en JSON (JavaScript Object Notation). Ce sont des séries de paires clés-valeurs séparées par des virgules, entre des accolades. Les objets peuvent être enregistrés dans une variable :

let myNFT = {
name: 'Ape in the evening',
author: 'Trendy Artist',
rarity: 250,
isAvailable: true
};

notation pointée (dot notation)
>> let bookTitle = myBook.title; 
"Ape in the evening"

>> let bookPages = myBook.numberOfPages 
250

notation bracket (bracket notation)
let bookTitle = myBook["title"]; // "Ape in the evening"
let bookPages = myBook["numberOfPages"]; // 250

let propertyToAccess = "title";
let bookTitle = myBook[propertyToAccess]; // "Ape in the evening"

Classes

Les classes sont déclarées ainsi :

class myNFT {
  constructor(artiste) {
    this.artiste = artiste;
  }

Le constructeur d'une classe est la fonction qui est appelée quand on crée une nouvelle instance de cette classe avec le mot clé new.

Pour attribuer le titre, l'auteur et le nombre de pages reçus à cette instance, utilisez le mot clé   this  et la notation dot. Même pas besoin de déclarer des propriétés.

class myNFT {
    constructor(artiste, name, adn) {
    this.artiste = artiste;
    this.name = name;
    this.adn = adn;
    }
}

Vous pouvez créer des instances par le mot clé new :

let myNFT = new myNFT("Trendy Artist", "Ape in the evening", 250);

Héritage de Classe


Il est possible pour une classe d'hériter d'une classe existante :

class Car {
  constructor(name) {
    this.brand = name;
  }

  present() {
    return 'I have a ' + this.brand;
  }
}

class Model extends Car {
  constructor(name, mod) {
    super(name);
    this.model = mod;
  }  
  show() {
      return this.present() + ', it is a ' + this.model
  }
}
const mycar = new Model("Ford", "Mustang");
mycar.show();

The super() method refers to the parent class.

By calling the super() method in the constructor method, we call the parent's constructor method and gets access to the parent's properties and methods


class BankAccount {
constructor(owner, balance) {
this.owner = owner;
this.balance = balance;
}

showBalance() {
console.log("Solde: " + this.balance + " EUR");
}

deposit(amount) {
console.log("Dépôt de " + amount + " EUR");
this.balance += amount;
this.showBalance();
}

withdraw(amount) {
if (amount > this.balance) {
console.log("Retrait refusé !");
} else {
console.log("Retrait de " + amount + " EUR");
this.balance -= amount;
this.showBalance();
}
}
}

Fonctions

Exemple de fonction 
hello = function() {
  return "Hello World!";
}

Fonction avec 2 paramètres
function afficherDeuxValeurs(valeur1, valeur2) {
      console.log('Première valeur:' + valeur1);
      console.log('Deuxième valeur:' + valeur2);
}

// On exécute la fonction
afficherDeuxValeurs(12, 'Bonjour');

// On définit la fonction
const calculateAverageRating = (ratings) => {

if(ratings.length === 0) {
return 0;
}

let sum = 0;
for (let rating of ratings) {
sum += rating;
}

    return sum / ratings.length;
}

Fonction fléchées

Sans paramètre
hello = () => {
  return "Hello World!";
}

Un paramètre
const getWordCount = (stringToTest) => {
    const wordArray = stringToTest.split(" ");
    return wordArray.length;
}

Deux paramètres
const showProduct = (name, price)  => {
  console.log(`The product ${name} costs ${price}$.`);
};

Fonction fléchée avec retour par défaut
It gets shorter! If the function has only one statement, and the statement returns a value, you can remove the brackets and the return keyword:
hello = () => "Hello World!";

hello = (val) => "Hello " + val;

In fact, if you have only one parameter, you can skip the parentheses as well:

Arrow Function Without Parentheses:
hello = val => "Hello " + val;

What About this?
The handling of this is also different in arrow functions compared to regular functions.

In short, with arrow functions there are no binding of this.

In regular functions the this keyword represented the object that called the function, which could be the window, the document, a button or whatever.

With arrow functions, the this keyword always represents the object that defined the arrow function.

Let us take a look at two examples to understand the difference.

Both examples call a method twice, first when the page loads, and once again when the user clicks a button.

The first example uses a regular function, and the second example uses an arrow function.

The result shows that the first example returns two different objects (window and button), and the second example returns the Header object twice.

Statiques

class BePolite {
    
static sayHello() {
      console.log("Hello!");
}

static sayHelloTo(name) {
      console.log("Hello " + name + "!");
}

static add(firstNumber, secondNumber) {
return firstNumber + secondNumber;
}
}

BePolite.sayHello(); // imprime "Hello!""

BePolite.sayHelloTo("Will"); // imprime "Hello Will!""

const sum = BePolite.add(2, 3); // sum = 5

Opérateurs 

+
-
+=
-=
++
--

Instructions Conditionnelles

If/else

if (numberOfGuests == numberOfSeats) {// tous les sièges sont occupés
} else if (numberOfGuests < numberOfSeats) {
// autoriser plus d'invités
} else {
// ne pas autoriser de nouveaux invités
}

Il y a deux façons de vérifier si deux valeurs sont égales en JavaScript : == et ===, aussi appelées égalité simple et égalité stricte :

l'égalité simple vérifie la valeur, mais pas le type. Donc ceci renvoie la valeur true :
5 == "5"

par contre, l'égalité stricte vérifie à la fois la valeur et le type. Donc :
5 === "5"

renvoie   false  , car on compare un   number  à une   string  .

De même, il y a deux opérateurs d'inégalité,   !=  et   !==  , avec la même distinction.

Switch

switch (firstUser.accountLevel) {
    case 'normal':
        console.log('You have a normal account!');
        break;
    case 'premium':
        console.log('You have a premium account!');
        break;
    case 'mega-premium':
        console.log('You have a mega premium account!');
        break;
    default:
        console.log('Unknown account type!');
}

For

const numberOfPassengers = 10;

for (let i = 0; i < numberOfPassengers; i++) {
console.log("Passager embarqué !");
}

const passengers = ["Alexander","Kate'","Audrey","Tatiana"]

for (let i in passengers) {
console.log("Embarquement du passager " + passengers[i]);
}

for (let passenger of passengers) {
console.log("Embarquement du passager " + passenger);
}

While

while (seatsLeft > 0 && passengersStillToBoard > 0) {

passengersBoarded++; // un passager embarque

passengersStillToBoard--; // donc il y a un passager de moins à embarquer

seatsLeft--; // et un siège de moins

}

Try Catch

try {
// code susceptible à l'erreur ici
} catch (error) {
// réaction aux erreurs ici
}

Opérateur Spread

Spread syntax (...) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected. It allows us to quickly copy all or part of an existing array or object into another array or object.

For function calls:

myFunction(...iterableObj); // pass all elements of iterableObj as arguments to function myFunction
For array literals:

[...iterableObj, '4', 'five', 6]; // combine two arrays by inserting all elements from iterableObj
For object literals (new in ECMAScript 2018):

let objClone = { ...obj }; // pass all key:value pairs from an object 

Spread Operator
The JavaScript spread operator (...) allows us to quickly copy all or part of an existing array or object into another array or object.

Example
const numbersOne = [1, 2, 3];
const numbersTwo = [4, 5, 6];
const numbersCombined = [...numbersOne, ...numbersTwo];

The spread operator is often used in combination with destructuring.

Example
Assign the first and second items from numbers to variables and put the rest in an array:

const numbers = [1, 2, 3, 4, 5, 6];

const [one, two, ...rest] = numbers;

We can use the spread operator with objects too:

Example
Combine these two objects:

const myVehicle = {
  brand: 'Ford',
  model: 'Mustang',
  color: 'red'
}

const updateMyVehicle = {
  type: 'car',
  year: 2021, 
  color: 'yellow'
}

const myUpdatedVehicle = {...myVehicle, ...updateMyVehicle}

Notice the properties that did not match were combined, but the property that did match, color, was overwritten by the last object that was passed, updateMyVehicle. The resulting color is now yellow.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
Spread syntax (...) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// expected output: 6

console.log(sum.apply(null, numbers));
// expected output: 6

Destructuration

Here is the old way of assigning array items to a variable:


const vehicles = ['mustang', 'f-150', 'expedition'];

// old way
const car = vehicles[0];
const truck = vehicles[1];
const suv = vehicles[2];
Here is the new way of assigning array items to a variable:
If we only want the car and suv we can simply leave out the truck but keep the comma:
const vehicles = ['mustang', 'f-150', 'expedition'];
const [car,, suv] = vehicles;
Destructuring comes in handy when a function returns an array:
Example
function calculate(a, b) {
const add = a + b;
const subtract = a - b;
const multiply = a * b;
const divide = a / b;
return [add, subtract, multiply, divide];
}
const [add, subtract, multiply, divide] = calculate(4, 7);

Here is the new way of using an object inside a function:

With destructuring:
const vehicleOne = {
  brand: 'Ford',
  model: 'Mustang',
  type: 'car',
  year: 2021, 
  color: 'red'
}

myVehicle(vehicleOne);

function myVehicle({type, color, brand, model}) {
  const message = 'My ' + type + ' is a ' + color + ' ' + brand + ' ' + model + '.';
}

Notice that the object properties do not have to be declared in a specific order.
We can even destructure deeply nested objects by referencing the nested object then using a colon and curly braces to again destructure the items needed from the nested object:

Example
const vehicleOne = {
  brand: 'Ford',
  model: 'Mustang',
  type: 'car',
  year: 2021, 
  color: 'red',
  registration: {
    city: 'Houston',
    state: 'Texas',
    country: 'USA'
  }
}

myVehicle(vehicleOne)

function myVehicle({ model, registration: { state } }) {
  const message = 'My ' + model + ' is registered in ' + state + '.';
}

Manipulation du DOM

Récupérez l'élément ayant pour ID main-content grâce à son ID ;
let listeEl = document.querySelector("article > ul.important > li")

console.log(listeEl.nextElementSibling);

console.log("#main-content", document.getElementById("main-content"));

Récupérez les éléments ayant pour classe  important  ;
console.log(".important", document.getElementsByClassName("important"));

Récupérez les éléments de type  article  ;
console.log("article", document.getElementsByTagName("article"));

Récupérez les éléments de type  li qui sont dans une liste ul ayant la classe  important . Cette liste doit elle-même être dans un article (article ) ;

const liItem = document.querySelector("article ul.important > li");
console.log("article ul.important > li", liItem);

En reprenant le résultat de la tâche précédente, récupérez l'élément li suivant de la liste ul .
console.log("nextElementSibling", liItem.nextElementSibling);



Pour commencer, voyons déjà les propriétés permettant de modifier directement le contenu de notre élément. Les deux principales sont :  innerHTML  et  textContent .   

innerHTML  demande à ce que vous entriez du texte représentant un contenu HTML. Par exemple :  "<p>Voici un exemple de contenu pour <strong>innerHTML</strong></p>" .

La propriété  textContent , quant à elle, demande un simple texte qui ne sera pas interprété comme étant du HTML. Si on reprend l'exemple du dessus, le mot innerHTML ne sera pas en gras, et les balises HTML seront visibles comme le reste du texte.

Modifier classes

elt.classList.add("nouvelleClasse");    // Ajoute la classe nouvelleClasse à l'élément
elt.classList.remove("nouvelleClasse"); // Supprime la classe nouvelleClasse que l'on venait d'ajouter
elt.classList.contains("nouvelleClasse");   // Retournera false car on vient de la supprimer
elt.classList.replace("oldClass", "newClass"): // Remplacera oldClass par newClass si oldClass était présente sur l'élément

Styles
elt.style.color = "#fff";      // Change la couleur du texte de l'élément à blanche
elt.style.backgroundColor = "#000"; // Change la couleur de fond de l'élément en noir
elt.style.fontWeight = "bold"; // Met le texte de l'élément en gras

attributs
elt.setAttribute("type", "password");   // Change le type de l'input en un type password
elt.setAttribute("name", "my-password");    // Change le nom de l'input en my-password
elt.getAttribute("name");               // Retourne my-password

Enfants
const newElt = document.createElement("div");
let elt = document.getElementById("main");

elt.appendChild(newElt);

const newElt = document.createElement("div");
let elt = document.getElementById("main");
elt.appendChild(newElt);

elt.removeChild(newElt);    // Supprime l'élément newElt de l'élément elt
elt.replaceChild(document.createElement("article"), newElt);    // Remplace l'élément newElt par un nouvel élément de type article

Les Evènements

Un événement est une réaction à une action émise par l'utilisateur, comme le clic sur un bouton ou la saisie d'un texte dans un formulaire.

Un événement en JavaScript est représenté par un nom ( click ,  mousemove ...) et une fonction que l'on nomme une  callback . Un événement est par défaut propagé, c'est-à-dire que si nous n'indiquons pas à l'événement que nous le traitons, il sera transmis à l'élément parent, et ainsi de suite jusqu'à l'élément racine.

Cette fonction  callback , c'est nous qui allons la spécifier. Elle sera appelée à chaque fois que l'action que l'on désire suivre est exécutée. Cela signifie que si l'on désire suivre le clic sur un élément, notre fonction sera appelée à chaque fois que l'utilisateur cliquera sur cet élément. 

addEventListener(<event>, <callback>)  (doc) prend en paramètres le nom de l'événement à écouter (voici la liste des événements existants), et la fonction à appeler dès que l'événement est exécuté.

Doc addEventListener : https://developer.mozilla.org/fr/docs/Web/API/EventTarget/addEventListener
Listes des évènements : https://developer.mozilla.org/fr/docs/Web/Events

const elt = document.getElementById('mon-lien');    // On récupère l'élément sur lequel on veut détecter le clic
elt.addEventListener('click', function(event) {          // On écoute l'événement click
    elt.innerHTML = "C'est cliqué !";               // On change le contenu de notre élément pour afficher "C'est cliqué !"
    event.preventDefault();                         // On utilise la fonction preventDefault de notre objet event pour empêcher le comportement par défaut de cet élément lors du clic de la souris

});

    event.stopPropagation();

Souris

Détectez le mouvement de la souris
https://developer.mozilla.org/fr/docs/Web/Events/mousemove
Afin de détecter le mouvement de la souris, il nous faut écouter l'événement  mousemove  (doc).  Cet événement nous fournit un objet de type  MouseEvent . C'est-à-dire que dès que la souris bouge, notre fonction callback sera appelée avec un paramètre de type  MouseEvent , qui contient les données sur le mouvement de la souris.

Voici, entre autres, ce que cet objet nous permet de récupérer :

  • clientX  /  clientY  : position de la souris dans les coordonnées locales (contenu du DOM) ;
  • offsetX  /  offsetY  : position de la souris par rapport à l'élément sur lequel on écoute l'événement 
  • pageX  /  pageY  : position de la souris par rapport au document entier ;
  • screenX  /  screenY  : position de la souris par rapport à la fenêtre du navigateur ;
  • movementX  /  movementY  : position de la souris par rapport à la position de la souris lors du dernier événement  mousemove
Documentation
https://developer.mozilla.org/fr/docs/Web/API/Element

Appeler une API

fetch(“https://mockbin.com/request”)
  .then(function(res) {
    if (res.ok) {
      return res.json();
    }
  })
  .then(function(value) {
    console.log(value);
  })
  .catch(function(err) {
    // Une erreur est survenue
  });

 nous appelons la fonctionthen()pour récupérer le résultat de la requête au format json en ayant vérifié au préalable que la requête s’était bien passée avec res.ok. Ce résultat json étant lui aussi une Promise, nous le retournons et récupérons sa vraie valeur dans la fonction then() suivante.

L'objet Promise (pour « promesse ») est utilisé pour réaliser des traitements de façon asynchrone. Une promesse représente une valeur qui peut être disponible maintenant, dans le futur voire jamais.

https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Using_promises

function askHello() {
  fetch("https://mockbin.com/request?greetings=salut")
    .then(function(res) {
    if (res.ok) {
      return res.json();
    }
  })
  .then(function (res) {
    document.getElementById("hello-result").innerHTML = res.queryString.greetings;
  });
};

document.getElementById("ask-hello").addEventListener('click', askHello);

function getCodeValidation() {
  return document.getElementById("code-validation");
}

function disableSubmit(disabled) {
  if (disabled) {
    document
      .getElementById("submit-btn")
      .setAttribute("disabled", true);
  } else {
    document
      .getElementById("submit-btn")
      .removeAttribute("disabled");
  }
}

document
  .getElementById("code")
  .addEventListener("input", function(e) {
  if (/^CODE-/.test(e.target.value)) {
    getCodeValidation().innerText = "Code valide";
    disableSubmit(false);
  } else {
    getCodeValidation().innerText = "Code invalide";
    disableSubmit(true);
  }
});

https://developer.mozilla.org/en-US/docs/Web/API/Response/json

Fetch

https://developer.mozilla.org/fr/docs/Web/API/Fetch_API/Using_Fetch

fetch("http://url-service-web.com/api/users", {
method: “POST”,
headers: { 
'Accept': 'application/json', 
'Content-Type': 'application/json' 
},
body: JSON.stringify(jsonBody)
});

function send(e) {
e.preventDefault();
fetch("https://mockbin.com/request", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({value: document.getElementById("value").value})
})
.then(function(res) {
if(res.ok) {
return res.json();
}
})
.then(function(res) {
document.getElementById("result").innerHTML = res.postData.text;
});


}

document
  .getElementById("form")
  .addEventListener('submit', send);

setTimeout(function() {
    console.log("I'm here!")
}, 5000);

console.log("Where are you?");

Callbacks

Pour gérer les erreurs avec les callbacks, la méthode la plus utilisée est de prendre 2 paramètres dans notre callback. Le 2e paramètre est notre donnée et le 1er est l'erreur. Si elle n'est pas null ou undefined,  elle contiendra un message d'erreur indiquant qu'une erreur est intervenue.

fs.readFile(filePath, function(err, data) {
    if (err) {
        throw err;
    }
    // Do something with data
});


Enchainer les requetes

callbacks

Voyons ensemble comment faire nos 2 requêtes en parallèle, suivies d'une requête en séquence avec les callbacks. Et vous verrez, ça peut vite devenir complexe !

Pour cet exemple, nous partons du principe que nous avons accès à 2 fonctions (get  et  post). Elles font respectivement une requête  GET  et une requête  POST et elles prennent en paramètre :

l'URL de la requête,

une callback à exécuter quand on a le résultat (avec une variable d'erreur en premier paramètre).

var GETRequestCount = 0;
var GETRequestResults = [];

function onGETRequestDone(err, result) {
    if (err) throw err;
    
    GETRequestCount++;
    GETRequestResults.push(result);
    
    if (GETRequestCount == 2) {
        post(url3, function(err, result) {
            if (err) throw err;
            
            // We are done here !
        });
    }
}

get(url1, onGETRequestDone);
get(url2, onGETRequestDone);

Comme vous pouvez le voir, le code est assez particulier à lire. Il y a d'autres façons d'écrire ce code, mais ça reste une des façons les plus simples et rapides à écrire.

Afin d'exécuter 2 requêtes  GET  en même temps, nous pouvons appeler 2 fois la fonction  get(). Étant donné que cette fonction est asynchrone, elle ne bloquera pas l'exécution du code. Ainsi l'autre fonction  get()  sera aussi appelée alors que la première ne sera pas encore terminée. C'est comme ça qu'on peut avoir 2 requêtes en parallèle.

Par contre, nous voulons exécuter une requête  POST  une fois que les 2 requêtes  GET  sont terminées, et pas avant ! Pour ce faire, nous devons savoir si les requêtes  GET  sont terminées. C'est pour ça que la variable  GETRequestCount  est créée. On va l'incrémenter dans la fonction callback que l'on a envoyée aux appels à  get() , et si on atteint 2 (le nombre de requêtes  GET qu'on a faites), alors on va exécuter la requête  POST .

GETRequestResults  sert à conserver les réponses des requêtes  GET , car on ne les a pas toutes les 2 en même temps.

Promesses

Promesses

Les promise, ou promesses en français, sont un peu plus complexes mais bien plus puissantes et faciles à lire que les callbacks.

Lorsque l'on exécute du code asynchrone, celui-ci va immédiatement nous retourner une "promesse" qu'un résultat nous sera envoyé prochainement.

Cette promesse est en fait un objet Promise qui peut être  resolve  avec un résultat, ou  reject  avec une erreur.

Lorsque l'on récupère une  Promise , on peut utiliser sa fonction  then()  pour exécuter du code dès que la promesse est résolue, et sa fonction  catch()  pour exécuter du code dès qu'une erreur est survenue.

The constructor syntax for a promise object is:

let promise = new Promise(function(resolve, reject) {
  // executor (the producing code, "singer")
});

La fonction passée à la nouvelle Promise est appellée executor. Quand un nouvelle promesse est crée, la fonction executor est automatiquement executée. ELle contient le code qui retournera éventuellement une résultat.

Les arguments resolve et reject sont des callbacks fournis par le langage JavaScript. 

Quand la fonction executor obtient un résultat, elle appelle un de ces callbacks:

resolve(value) — si le job s'est bien terminé , value contient le résultat.
reject(error) — si une erreur est survenue, error est un objet error.

The promise object returned by the new Promise constructor has these internal properties:

state — initially "pending", then changes to either "fulfilled" when resolve is called or "rejected" when reject is called.
result — initially undefined, then changes to value when resolve(value) called or error when reject(error) is called.

let promise = new Promise(function(resolve, reject) {
  // the function is executed automatically when the promise is constructed

  // after 1 second signal that the job is done with the result "done"
  setTimeout(() => resolve("done"), 1000);
});

Voyons avec un exemple concret pour mieux comprendre :

functionThatReturnsAPromise()
    .then(function(data) {
        // Do somthing with data 
    })
    .catch(function(err) {
        // Do something with error
    });


async function fonctionAsynchrone1() {/* code asynchrone */}
async function fonctionAsynchrone2() {/* code asynchrone */}

async function fonctionAsynchrone3() {
 const value1 = await fonctionAsynchrone1();
 const value2 = await fonctionAsynchrone2();
 return value1 + value2;
}

et’s start with the async keyword. It can be placed before a function, like this:

async function f() {
  return 1;
}
The word “async” before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically.

For instance, this function returns a resolved promise with the result of 1; let’s test it:

async function f() {
  return 1;
}

f().then(alert); // 1
…We could explicitly return a promise, which would be the same:

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1
So, async ensures that the function returns a promise, and wraps non-promises in it. Simple enough, right? But not only that. There’s another keyword, await, that works only inside async functions, and it’s pretty cool.

https://javascript.info/async-await

The keyword await makes JavaScript wait until that promise settles and returns its result.


async function getNumber1() {
  return 10;
}

async function getNumber2() {
  return 4;
}

async function compute() {
  let number1 = await getNumber1();
  let number2 = await getNumber2();
  return number1 + number2;
}

compute()
  .then(function(res) {
  document
    .getElementById("result")
    .innerHTML = res;
});


Grâce à la fonction   Promise.all  , voyons comment exécuter nos requêtes en parallèle et en séquence avec les  Promise .

Pour cet exemple, nous partons du principe que nous avons accès à 2 fonctions (  get  et  post  ) qui font respectivement une requête  GET  et une requête  POST  quand on leur passe en paramètre l'URL de la requête. Ces fonctions retourneront une  Promise  avec le résultat de la requête.

Promise.all([get(url1), get(url2)])
    .then(function(results) {
        return Promise.all([results, post(url3)]];
    })
    .then(function(allResults) {
        // We are done here !
    });
Ici, nous utilisons la fonction  Promise.all  qui prend en paramètre une liste de  Promise  (cela peut aussi être de simples valeurs qui sont alors transformées en  Promise  résolues), et qui permet de toutes les exécuter en parallèle et de retourner une nouvelle  Promise  qui sera résolue quand toutes les  Promise  seront résolues.

Ainsi, la fonction  then()  recevra les résultats de toutes les  Promise  sous forme d'un tableau.

Afin d'exécuter notre requête  POST  une fois que les requêtes  GET  sont terminées, nous l'exécutons donc dans la fonction  then().

Notez que dans la fonction  then(), nous faisons encore une fois appel à la fonction  Promise.all  en lui passant les résultats des requêtes  GET  et notre requête  POST . Étant donné que  Promise.all  considère les simples valeurs comme des  Promise  résolues, cela nous permet, dans le prochain  then() , de récupérer une liste qui contient les résultats des requêtes  GET  et le résultat de la requête  POST  : allResults = [ [ getResult1, getResult2 ], postResult ] . 

async/await

Finalement, voyons comment exécuter le même code mais avec  async  /  await .

Pour cet exemple, nous partons du principe que nous avons accès à 2 fonctions (  get  et  post  ) qui font respectivement une requête  GET  et une requête  POST  quand on leur passe en paramètre l'URL de la requête. Ces fonctions sont asynchrones (avec le mot clé  async ).

async function requests() {
    var getResults = await Promise.all([get(url1), get(url2)]);
    var postResult = await post(url3);
    return [getResults, postResult];
}

requests().then(function(allResults) {
    // We are done here !
});
Nous utilisons aussi la fonction  Promise.all  dans ce code, car c'est comme ça que l'on peut exécuter des fonctions asynchrones en parallèle (rappelez-vous que  async  correspond en arrière-plan à une  Promise ).

Par contre, ici, nous utilisons  await  devant  Promise.all  afin d'attendre la fin de l'exécution des 2 requêtes  GET , puis nous utilisons  await  devant la requête  POST  afin d'attendre son résultat. Puis nous renvoyons un tableau avec tous les résultats.

Lorsque nous appelons la fonction  requests() , ici, nous utilisons  then()  pour récupérer tous les résultats (mais vous auriez aussi pu utiliser  await  au sein d'une autre fonction avec le mot clé  async ).

Méthodes de Tableaux

Méthode map

La méthode map() permet facilement d'itérer sur des données et de retourner un tableau d'éléments. On trouve également les méthodes forEach(), filter(), reduce(), etc., qui permettent de manipuler des tableaux.

<ul className='nft-list'>

{nftList.map(({ id, cover, name, water, light }) => (

<NftItem
id={id}
cover={cover}
name={name}
water={water}
light={light}
/>
))}

</ul>

Installation

Une interface de développement est nécessaire et Visual Studio Code est très bien.

Pour développer en JavaScript, il faudra du code, le js, et un environnement d'execution, historiquement un navigateur web mais de nos jours des serveurs d'application existent.

Node.js est une plateforme logicielle libre en JavaScript, orientée vers les applications réseau évènementielles hautement concurrentes qui doivent pouvoir monter en charge.

Elle utilise la machine virtuelle V8, la librairie libuv pour sa boucle d'évènements, et implémente sous licence MIT les spécifications CommonJS.

Parmi les modules natifs de Node.js, on retrouve http qui permet le développement de serveur HTTP. Ce qui autorise, lors du déploiement de sites internet et d'applications web développés avec Node.js, de ne pas installer et utiliser des serveurs webs tels que Nginx ou Apache.

Concrètement, Node.js est un environnement bas niveau permettant l’exécution de JavaScript côté serveur. Nous allons l'utiliser dans un premier temps pour développer et ensuite pour executer notre code.

Source : Wikipedia

Installation de node sous linux Mint : 

Source : SoftHints

sudo apt update
sudo apt install nodejs

Gestionnaire de Paquet NPM

npm est le gestionnaire de paquets par défaut pour l'environnement d'exécution JavaScript Node.js.

npm se compose d'un client en ligne de commande, également appelé npm, et d'une base de données en ligne de paquets publics et privés payants, appelée le registre npm. Le registre est accessible via le client, et les paquets disponibles peuvent être parcourus et recherchés via le site Web de npm. Le gestionnaire de paquets et le registre sont gérés par npm, Inc.

npm est normalement installé par défaut avec NodeJs mais au cas ou :
sudo apt install npm

L'installation de Node.js depuis les dépôts sera obsolète. Utiliser le module n pour mettre à jour :
npm install n -g

Then you can install the stable Node.js by:
n stable

or the latest:
n latest

Extensions

Un linter va vous permettre de trouver des erreurs dans votre code et de mettre en place des conventions de code.
Un minifier va vous permettre de réduire la taille de votre code pour que les navigateurs le chargent plus vite.
un bundler va regrouper tous vos fichiers en un seul afin que le navigateur soit plus rapide à charger votre code ;
un transpiler va vous permettre d’utiliser les nouvelles fonctionnalités du langage JavaScript tout en restant compatible avec tous les navigateurs.

Configurer son projet

Ajouter npm au projet
npm init

https://webpack.js.org/

webpack.config.json

créer un fichier  webpack.config.js  à la racine du projet. C'est le fichier qui servira de configuration à Webpack pour savoir comment il doit compiler notre projet. 

const path = require('path');

module.exports = {
  mode: "production",
  entry: {
    app: "./src/index.js"
  },
  output: {
    filename: "[name].bundle.js",
    path: path.resolve(__dirname, "dist")
  }
};

Package JSON

{
"name": "firstpack",
"version": "1.0.0",
"description": "sources and examples in js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [
"test",
"tutorial"
],
"author": "sugarhill",
"license": "ISC",
"devDependencies": {
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2"
}
}


npm run build

NPM

npm uninstall

Transpiler avec Babel
npm install --save-dev babel-loader @babel/core @babel/preset-env babel-polyfill

Serve
webpack serve mini serveur web

pour aller plus vite, il est possible d'utiliser Create React App, voir React page.


Commentaires

Posts les plus consultés de ce blog

Sécurité des Applications

Principes de la Programmation Orientée Objet

Principe de Responsabilité Unique