La syntaxe de JavaScript est l'ensemble des règles qui définissent un programme JavaScript correctement structuré.
Les exemples ci-dessous utilisent la console.log()fonction présente dans la plupart des navigateurs pour la sortie de texte standard .
La bibliothèque standard JavaScript ne dispose pas de fonction d'affichage de texte standard officielle (à l'exception de `<script> document.write`). Étant donné que JavaScript est principalement utilisé pour le script côté client dans les navigateurs web modernes , et que presque tous les navigateurs web fournissent la fonction `alert`, `<script>` alertpeut également être utilisé, mais il est peu courant.
TypeScript , qui étend JavaScript avec des annotations de type et des fonctionnalités supplémentaires, possède la même syntaxe ainsi que ses propres fonctionnalités supplémentaires.
Brendan Eich a résumé l'origine de la syntaxe dans le premier paragraphe de la spécification JavaScript 1.1 comme suit :
JavaScript emprunte la majeure partie de sa syntaxe à Java , mais hérite également d' Awk et de Perl , avec une certaine influence indirecte de Self dans son système de prototypes d'objets.
La syntaxe JavaScript est en grande partie dérivée de la syntaxe Java , qui elle-même est dérivée de la syntaxe C et de la syntaxe C++ .
Bases
Mots clés
Mots-clés réservés
Les mots suivants sont des mots-clés et ne peuvent en aucun cas être utilisés comme identifiants.
ECMAScript 5/6 :sensible à la casse . Il est courant de commencer le nom d'un constructeur par une majuscule et le nom d'une fonction ou d'une variable par une minuscule.Exemple:
Deux problèmes se posent : cinq jetons peuvent soit commencer une déclaration, soit être l’extension d’une déclaration complète ; et cinq productions restreintes, où les sauts de ligne ne sont pas autorisés à certains endroits, ce qui peut entraîner une analyse incorrecte.
Les cinq éléments problématiques sont la parenthèse ouvrante " (", le crochet ouvrant " [", la barre oblique " /", le plus " +" et le moins " -". Parmi ceux-ci, la parenthèse ouvrante est fréquente dans le modèle d'expression de fonction immédiatement invoquée , le crochet ouvrant apparaît parfois, tandis que les autres sont assez rares. Exemple :
Les commentaires sur une seule ligne commencent par //et se poursuivent jusqu'à la fin de la ligne. Un deuxième type de commentaires est également possible ; ceux-ci commencent /*et se terminent par */et peuvent être utilisés pour les commentaires sur plusieurs lignes.
Un troisième type de commentaire, le commentaire hashbang, commence par un tiret #!et se poursuit jusqu'à la fin de la ligne. Il n'est valide qu'en début de fichier et est destiné à être utilisé dans les environnements en ligne de commande .
varpour les variables de portée fonctionnelle et let`var` constpour les variables de bloc . Avant ES6, seule varl'instruction `var` permettait de déclarer une variable. Les valeurs assignées aux variables déclarées avec `var` constne peuvent pas être modifiées, mais leurs propriétés peuvent l'être. `var` varne doit plus être utilisé, car `var` letet const`var` sont pris en charge par les navigateurs modernes. L'identifiant d'une variable doit commencer par une lettre, un trait de soulignement (` __`) ou un signe dollar (`$ $`), et les caractères suivants peuvent également être des chiffres (` 0-9$`). JavaScript est sensible à la casse : les caractères majuscules « A » à « Z » sont différents des caractères minuscules « a » à « z ».ISO 8859-1 ou Unicode (ou \uXXXXles séquences d'échappement Unicode) peuvent être utilisés dans les identificateurs. Dans certaines implémentations JavaScript, le symbole arobase ( @ ) peut être utilisé dans un identificateur, mais cela est contraire aux spécifications et n'est pas pris en charge par les implémentations plus récentes.une portée lexicale au niveau de la fonction , tandis que celles déclarées avec `const` letou ` constlet` ont une portée au niveau du bloc . Étant donné que les déclarations sont traitées avant l'exécution de tout code, une variable peut être initialisée et utilisée avant même d'être déclarée dans le code. On parle alors de…le hoisting , et il est équivalent àla déclaration anticipéeen haut de la fonction ou du bloc.Avec les instructions var`new` let, `new` et const`assign`, seule la déclaration est remontée ; les affectations ne le sont pas. Ainsi, une instruction `new` au milieu d'une fonction est équivalente à une déclaration en début de fonction et à une affectation à cet endroit précis. Cela signifie que les valeurs ne sont pas accessibles avant leur déclaration ; les références anticipées sont impossibles. Avec ` new`, la valeur d'une variable est ` null` jusqu'à son initialisation. Les variables déclarées avec `new` ou ` assign` ne sont pas accessibles tant qu'elles n'ont pas été initialisées ; y faire référence avant provoquera donc une erreur.varundefinedletconst
Les déclarations de fonctions, qui déclarent une variable et lui assignent une fonction , sont similaires aux instructions de variable, mais outre le fait de remonter la déclaration, elles remontent également l'assignation – comme si l'instruction entière apparaissait en haut de la fonction englobante – et permettent ainsi une référence anticipée : l'emplacement d'une instruction de fonction dans une fonction englobante est sans importance. Ceci diffère de l'assignation d'une expression de fonction à une variable dans une instruction var`if`, let`if` ou const`if`.
Par exemple,
letmot-clé.Déclaration et cession
Les variables déclarées en dehors d'une portée sont globales . Si une variable est déclarée dans une portée supérieure, elle est accessible par les portées enfants.
Lorsque JavaScript tente de résoudre un identifiant, il effectue sa recherche dans la portée locale. Si cet identifiant est introuvable, il poursuit sa recherche dans la portée externe suivante, et ainsi de suite le long de la chaîne de portée jusqu'à atteindre la portée globale où résident les variables globales. Si l'identifiant reste introuvable, JavaScript lève une ReferenceErrorexception.
Lors de l'attribution d'un identifiant, JavaScript suit exactement le même processus pour le récupérer, à ceci près que s'il est introuvable dans la portée globale , la variable est créée dans la portée où elle a été déclarée. Par conséquent, une variable jamais déclarée devient globale si elle lui est attribuée. Déclarer une variable (avec le mot-clé `global` var) dans la portée globale (c'est-à-dire en dehors de tout corps de fonction, ou bloc dans le cas de `let`/`const`), attribuer un identifiant jamais déclaré ou ajouter une propriété à l' objet global (généralement `window` ) crée également une nouvelle variable globale.
Notez que le mode strict de JavaScript interdit l'affectation d'une variable non déclarée, ce qui évite la pollution de l'espace de noms global.
Exemples
Voici quelques exemples de déclarations de variables et de portée :
UndefinedNumberBigIntStringBooleanSymbol
Certains types de données primitifs proposent également un ensemble de valeurs nommées qui représentent les limites de leurs frontières. Ces valeurs nommées sont décrites dans les sections appropriées ci-dessous.
Indéfini
Remarque : `undefined` est considéré comme un type primitif. Sauf conversion explicite, sa valeur peut se comporter de manière inattendue par rapport à d’autres types qui, dans un contexte logique, sont évalués à `false`.
; } // ... ou la troisièmeIci, l'appel isUndefined(my_var)génère une erreur ReferenceError si my_var est un identifiant inconnu, alors que ce n'est pas le cas.à virgule flottante double précision (norme IEEE 754) . Bien que ce format offre une précision de près de 16 chiffres significatifs , il ne peut pas toujours représenter exactement les nombres réels, notamment les fractions.
Cela pose problème lors de la comparaison ou de la mise en forme de nombres. Par exemple :
Ces trois valeurs spéciales correspondent et se comportent comme le décrit la norme IEEE-754 .
Le constructeur Number (utilisé comme une fonction), ou un opérateur unaire + ou -, peut être utilisé pour effectuer une conversion numérique explicite :
Lorsqu'il est utilisé comme constructeur, un objet enveloppe numérique est créé (bien qu'il soit de peu d'utilité) :
BigInt
En JavaScript, les nombres entiers sont représentés par le type à virgule flottante IEEE 754, ce qui signifie que les entiers ne peuvent être stockés en toute sécurité que si leur valeur se situe entre 0 Number.MIN_SAFE_INTEGERet Number.MAX_SAFE_INTEGER1. Les BigInts, quant à eux, représentent des entiers de toute taille, permettant ainsi aux programmeurs de stocker des entiers trop grands ou trop petits pour être représentés au format IEEE 754.
Il existe deux façons de déclarer une valeur BigInt. On npeut ajouter un entier à un entier, ou BigIntutiliser la fonction :
" caractères est une séquence de caractères. On peut créer des chaînes directement (littérales) en plaçant la série de caractères entre guillemets doubles ( ") ou simples (" '). Ces chaînes doivent tenir sur une seule ligne, mais peuvent inclure des caractères de nouvelle ligne échappés (comme `
`). La norme JavaScript autorise l' accent grave` (`\`) pour encadrer les chaînes littérales multilignes, ainsi que les expressions imbriquées grâce à la syntaxe ` ` . ${expression}const greeting = "Bonjour, monde !" ; const anotherGreeting = 'Salutations, habitants de la Terre.' ; const aMultilineGreeting = `Bien cordialement, John Doe.`// Les littéraux de gabarit convertissent les expressions évaluées en types et les interpolent dans la chaîne. const templateLiteral = `Voici ce qui est stocké dans anotherGreeting : ${ anotherGreeting } .` ; console . log ( templateLiteral ); // 'Voici ce qui est stocké dans anotherGreeting : 'Salutations, habitants de la Terre.'' console . log ( `Vous avez ${ Math . floor ( age )=> 18 ? "autorisé" : "non autorisé" } pour consulter cette page web` );
On peut accéder à chaque caractère d'une chaîne de caractères grâce à la méthode `charAt` (fournie par `String.prototype` ). C'est la méthode recommandée pour accéder à des caractères individuels dans une chaîne, car elle fonctionne également dans les navigateurs anciens.immuables :
L'application de l' opérateur d'égalité (« ==" ») à deux chaînes de caractères renvoie vrai si les chaînes ont le même contenu, c'est-à-dire : la même longueur et la même séquence de caractères (la casse est importante pour les lettres). Ainsi :
Les citations du même type ne peuvent pas être imbriquées à moins d'être échappées .
Le constructeur String crée un objet chaîne (un objet contenant une chaîne de caractères) :);
Ces objets possèdent une méthode valueOf qui renvoie la chaîne primitive qu'ils contiennent :); typeof s ; // Est 'object'. typeof s . valueOf (); // Est 'string'.
L'égalité entre deux objets String ne se comporte pas comme avec les types primitifs de chaînes de caractères :); const s2 = new String ( "Hello !" ); s1 == s2 ; // Est faux, car ce sont deux objets distincts. s1 . valueOf () == s2 . valueOf (); // Est vrai.
booléen
JavaScript fournit un type de données booléen avec les valeurs littérales `true` et `false` . L' opérateur `typeof` renvoie la chaîne « boolean » pour ces types primitifs . Dans un contexte logique, `0` , `-0` , `null` , `NaN` , ` undefined` et la chaîne vide ( « » ) sont interprétés comme `false` en raison de la conversion automatique de type . Toutes les autres valeurs (le complément de la liste précédente) sont interprétées comme `true` , y compris les chaînes « 0 » , « false » et tout objet.Douglas Crockford préconise l'utilisation des termes « vrai » et « faux » pour décrire le comportement des valeurs de différents types lorsqu'elles sont évaluées dans un contexte logique, notamment dans les cas limites. Les opérateurs logiques binaires renvoyaient une valeur booléenne dans les premières versions de JavaScript, mais ils renvoient désormais l'un des opérandes. L'opérande de gauche est renvoyé s'il peut être évalué comme faux ( dans le cas d' une conjonction : `( )`) ou comme vrai (dans le cas d' une disjonction : `( )`) ; sinon, c'est l'opérande de droite qui est renvoyé. La conversion automatique de type par les opérateurs de comparaison peut différer en présence d'opérandes mixtes booléens et numériques (y compris les chaînes de caractères pouvant être évaluées comme un nombre ou les objets pouvant être évalués comme une telle chaîne), car l'opérande booléen sera comparé comme une valeur numérique. Ce comportement peut être inattendu. Une expression peut être explicitement convertie en un type primitif booléen en doublant l' opérateur de négation logique `:` (` !! `), en utilisant la fonction `Boolean()` ou en utilisant l' opérateur conditionnel ` :` ( `()` ).a && ba || bc? t: f
L'opérateur `new` permet de créer un objet encapsulant un booléen primitif. Cependant, l' opérateur `typeof` ne renvoie pas un booléen pour cet objet encapsulant, mais un objet . Comme tous les objets sont évalués à `true` , une méthode telle que `.valueOf()` ou `.toString() ` doit être utilisée pour récupérer la valeur encapsulée. Pour une conversion explicite vers le type `Boolean`, Mozilla recommande d'utiliser la fonction `Boolean()` (sans `new` ) plutôt que l'objet `Boolean`.); } else if ([] && {} && b && typeof b === "object" && b . toString () === "false" ) { console . log ( "Toujours ceci" ); }
Symbole
Les symboles sont une fonctionnalité introduite dans ES6 . Chaque symbole est garanti d'avoir une valeur unique et ils peuvent être utilisés pour l'encapsulation .
Exemple:
const x = Symbol ( 1 ); const y = Symbol ( 1 ); x === y ; // => fauxconst symbolObject = {}; const normalObject = {};// puisque x et y sont uniques, // ils peuvent être utilisés comme clés uniques dans un objet symbolObject [ x ] = 1 ; symbolObject [ y ] = 2 ;symbolObject [ x ]; // => 1 symbolObject [ y ]; // => 2// par rapport aux touches numériques normales normalObject [ 1 ] = 1 ; normalObject [ 1 ] = 2 ; // remplace la valeur de 1normalObject [ 1 ]; // => 2// Modifier la valeur de x ne modifie pas la clé stockée dans l'objet x = Symbol ( 3 ); symbolObject [ x ]; // => undefined// Modifier x à sa valeur initiale crée simplement un autre symbole unique : x = Symbol ( 1 ); symbolObject [ x ]; // => undefined
Il existe également des symboles bien connus .
L'une d'elles estSymbol.iterator ; si quelque chose implémente Symbol.iterator, il est itérable :
objets natifs
Le langage JavaScript fournit un ensemble d' objets natifs . Ces objets sont considérés comme faisant partie de la spécification JavaScript. Quel que soit l'environnement JavaScript, cet ensemble d'objets devrait toujours être disponible.
Tableau
Arrayconstructeur, conçu spécifiquement pour stocker des valeurs de données indexées par des clés entières. Contrairement au type Object de base, les tableaux sont prototypés avec des méthodes et des propriétés pour faciliter les tâches courantes du programmeur (par exemple, `map` join, slice`filter` et `map` push).Comme dans la famille C , les tableaux utilisent un schéma d'indexation à partir de zéro : une valeur insérée dans un tableau vide au moyen de la pushméthode occupe l'indice 0 du tableau.
Les tableaux possèdent une lengthpropriété dont la valeur est toujours supérieure à l'indice entier le plus élevé utilisé dans le tableau. Cette valeur est automatiquement mise à jour lorsqu'une propriété avec un indice encore plus élevé est créée. L'écriture d'un nombre inférieur dans cette lengthpropriété supprime les indices supérieurs.
Les éléments de Arrays peuvent être consultés en utilisant la notation d'accès aux propriétés d'objet normale :
Les deux exemples ci-dessus sont équivalents. Il n'est pas possible d'utiliser la notation pointée ni les chaînes de caractères avec d'autres représentations du nombre.
La déclaration d'un tableau peut utiliser soit une Arrayvaleur littérale, soit le Arrayconstructeur :
brown" , size : "large" }; dog [ "color" ]; // donne "brown" dog.color ; // donne également "brown"On peut utiliser les déclarations littérales d'objets et de tableaux pour créer rapidement des tableaux associatifs, multidimensionnels, ou les deux. (Techniquement, JavaScript ne prend pas en charge les tableaux multidimensionnels, mais on peut les simuler avec des tableaux de tableaux.)
Date
Un Dateobjet stocke un nombre de millisecondes signé, zéro représentant le 1er janvier 1970 à 00:00:00 UTC, avec une plage de ±10⁸ jours . Plusieurs arguments peuvent être fournis au Dateconstructeur. Notez que les mois sont indexés à partir de zéro.
Des méthodes d'extraction de champs sont fournies, ainsi qu'une fonction utiletoString :
Ces exceptions peuvent être interceptées par des blocs try...catch...finally comme décrit dans la section sur la gestion des exceptions .
Mathématiques
L' objet Math contient diverses constantes mathématiques (par exemple, radians , et non en degrés ou en grades .
| Propriété | Valeur renvoyée arrondie à 5 chiffres | Description |
|---|---|---|
| e : Base du logarithme naturel | ||
| Logarithme népérien de 2 | ||
| Logarithme en base 2 de Racine carrée de ½ | ||
| Racine carrée de 2 |
| Exemple | Valeur renvoyée arrondie à 5 chiffres | Description |
|---|---|---|
| Valeur absolue | ||
| rad = 45° | Arccosine | |
| Arcsinus | ||
| Arctangente du demi-cercle ( à ) | ||
| à ) | ||
| arrondir à l’entier supérieur ≥ argument | ||
| Cosinus | ||
| Fonction exponentielle : L'exponentiation (élevée à la puissance de) : Math.pow(x, y) donne x yNombre pseudo-aléatoire compris entre 0 (inclus) et 1 (exclu) | ||
| Sinus | ||
| Tangente |
Expression régulière
classes de personnages
Repeaters
Anchors
Sous-expression
drapeaux
Méthodes avancées
groupes de capture
Fonction
En JavaScript, chaque fonction est une instance du Functionconstructeur :
// x et y sont les arguments. 'return x + y' est le corps de la fonction, qui est le dernier argument de la liste. const add = new Function ( 'x' , 'y' , 'return x + y' ); add ( 1 , 2 ); // => 3
La fonction d'addition ci-dessus peut également être définie à l'aide d'une expression de fonction :
const add = function ( x , y ) { return x + y ; }; add ( 1 , 2 ); // => 3
En ES6, la syntaxe des fonctions fléchées a été introduite, permettant ainsi de rendre plus concises les fonctions renvoyant une valeur. thisContrairement aux expressions régulières, elles conservent également le type de l'objet global au lieu de l'hériter de l'objet sur lequel elles sont appelées function() {}.
const add = ( x , y ) => { return x + y ;}; // les valeurs peuvent également être retournées implicitement (c'est-à-dire qu'aucune instruction return n'est nécessaire) const addImplicit = ( x , y ) => x + y ;ajouter ( 1 , 2 ); // => 3 ajouterImplicite ( 1 , 2 ) // => 3
Pour les fonctions qui doivent être remontées, il existe une expression distincte :
fonction ajouter ( x , y ) { retourner x + y ; } ajouter ( 1 , 2 ); // => 3
Le hoisting permet aux utilisateurs d'utiliser la fonction avant qu'elle ne soit « déclarée » :
ajouter ( 1 , 2 ); // => 3, pas une erreur de référence fonction ajouter ( x , y ) { retourner x + y ; }
Une instance de fonction possède des propriétés et des méthodes.
fonction soustraire ( x , y ) { retourner x - y ; }console.log ( subtract.length ); // = > 2 , arité de la fonction (nombre d' arguments ) console.log ( subtract.toString ( ) ) ;/* "fonction soustraire(x, y) { retourner x - y; }" */
Opérateurs
L'opérateur « + » est surchargé : il sert à la concaténation de chaînes et à l'addition arithmétique. Cela peut poser problème en cas de mélange involontaire de chaînes et de nombres. En tant qu'opérateur unaire, il peut convertir une chaîne numérique en un nombre.
+-*/%**JavaScript prend en charge les opérateurs arithmétiques unaires suivants :
+ | Conversion unaire d'une chaîne de caractères en nombre |
- | Négation unaire (inverse le signe) |
++ | incrément (peut être préfixé ou postfixé) |
-- | décrément (peut être préfixé ou postfixé) |
=+=-=*=/=%=**=Attribution de types primitifs
[...foo]" en " [foo[0], foo[1], foo[2]]", et " this.bar(...foo);" en " this.bar(foo[0], foo[1], foo[2]);", et " { ...bar }" en { prop: bar.prop, prop2: bar.prop2 }.Lorsqu'il ...est utilisé dans une déclaration de fonction , il indique un paramètre `rest` . Ce paramètre doit être le dernier paramètre nommé de la liste des paramètres de la fonction. Il se verra attribuer une variable Arraycontenant tous les arguments passés à la fonction en sus des autres paramètres nommés. Autrement dit, il reçoit les arguments restants (d'où son nom).
Les paramètres REST sont similaires à argumentsl'objet `require` de JavaScript, qui est un objet de type tableau contenant tous les paramètres (nommés et anonymes) de l'appel de fonction courant. Contrairement à `require` arguments, cependant, les paramètres REST sont de véritables Arrayobjets, ce qui permet d'utiliser directement des méthodes telles que ` .slice()get` et `set`..sort()
Comparaison
== | égal |
!= | non égal |
> | supérieur à |
>= | supérieur ou égal à |
< | moins que |
<= | inférieur ou égal à |
=== | identique (égal et de même type) |
!== | non identiques |
Les variables faisant référence à des objets sont égales ou identiques uniquement si elles font référence au même objet :
Logique
JavaScript propose quatre opérateurs logiques :
- négation unaire (
NOT = !a) - disjonction binaire (
OR = a || b) et conjonction (AND = a && b) - conditionnel ternaire ( )
c? t: f
Dans le contexte d'une opération logique, toute expression est évaluée à vrai, sauf la suivante :
- Chaînes de caractères :
,'', - Nombres :
0,-0,NaN, - Spécial:
null,undefined, - Booléen :
false.
La fonction booléenne peut être utilisée pour convertir explicitement en un type primitifBoolean :
L'opérateur NOT évalue son opérande comme un booléen et renvoie sa négation. Son utilisation deux fois de suite, formant une double négation , convertit explicitement une expression en un type primitif booléen :
L'opérateur ternaire peut également être utilisé pour une conversion explicite :
Les expressions qui utilisent des fonctionnalités telles que la post-incrémentation ont un effet de bordi++ prévisible . JavaScript assure une évaluation court-circuitée des expressions ; l’opérande de droite n’est exécuté que si l’opérande de gauche ne suffit pas à déterminer la valeur de l’expression.
Affectation logique
??= | Affectation nulle |
||= | Ou logique |
&&= | Logique et affectation |
Bitwise
JavaScript prend en charge les opérateurs binaires suivants :
& | ET |
| | OU |
^ | XOR |
! | PAS |
<< | décaler vers la gauche (remplissage à zéro à droite) |
>> | Décalage à droite (propagation du signe) ; des copies du bit le plus à gauche (bit de signe) sont décalées depuis la gauche. |
>>> | Décalage vers la droite (remplissage à zéro à gauche). Pour les nombres positifs, le résultat est le même .>>>>> |
Exemples :
~Affectation bit à bit
JavaScript prend en charge les opérateurs d'affectation binaire suivants :
&= | et |
|= | ou |
^= | xor |
<<= | décaler vers la gauche (remplissage à zéro à droite) |
>>= | Décalage à droite (propagation du signe) ; des copies du bit le plus à gauche (bit de signe) sont décalées depuis la gauche. |
>>>= | Décalage vers la droite (remplissage à zéro à gauche). Pour les nombres positifs, le résultat est le même .>>=>>>= |
Exemples :
=++=Exemples :
??
??, the "nullish coalescing operator", which was added to the standard in ECMAScript's 11th edition. In earlier versions, it could be used via a Babel plugin, and in TypeScript. It evaluates its left-hand operand and, if the result value is not "nullish" (null or undefined), takes that value as its result; otherwise, it evaluates the right-hand operand and takes the resulting value as its result.In the following example, a will be assigned the value of b if the value of b is not null or undefined, otherwise it will be assigned 3.
null, undefined, , 0, NaN, and of course, false.In the following example, a will be assigned the value of b if the value of b is truthy, otherwise it will be assigned 3.
Switch statement
The syntax of the JavaScript switch statement is as follows:
For loop
The syntax of the JavaScript for loop is as follows:
Because the availability of with statements hinders program performance and is believed to reduce code clarity (since any given variable could actually be a property from an enclosing goto is a reserved word,goto is not implemented in JavaScript.
Functions are first class objects and may be assigned to other variables.
The number of arguments given when calling a function may not necessarily correspond to the number of arguments in the function definition; a named argument in the definition that does not have a matching argument in the call will have the value closures by remembering the outer function's local variables even after the outer function has exited.
An anonymous function is simply a function without a name and can be written either using function or arrow notation. In these equivalent examples an anonymous function is passed to the map function and is applied to each of the elements of the array.
[1,2,3].map(function(x){returnx*2;);//returns [2,4,6][1,2,3].map((x)=>{returnx*2;});//same result
A generator function is signified placing an * after the keyword function and contains one or more yield statements. The effect is to return a value and pause execution at the current state. Declaring an generator function returns an iterator. Subsequent calls to iterator.next() resumes execution until the next yield. When the iterator returns without using a yield statement there are no more values and the done property of the iterator is set to true.
With the exception of iOS devices from Apple, generators are not implemented for browsers on mobile devices.
Async/await
Many libraries provide promise objects that can also be used with await, as long as they match the specification for native JavaScript promises. However, promises from the jQuery library were not Promises/A+ compatible until jQuery 3.0.
Below is an example (modified from this article):
Node.js version 8 includes a utility that enables using the standard library callback-based methods as promises.
Objects
For convenience, types are normally subdivided into primitives and objects. Objects are entities that have an identity (they are only equal to themselves) and that map property names to values ("slots" in prototype-based programming terminology). Objects may be thought of as associative arrays or hashes, and are often implemented using these data structures. However, objects have additional features, such as a prototype chain, which ordinary associative arrays do not have.
JavaScript has several kinds of built-in objects, namely Array, Boolean, Date, Function, Math, Number, Object, RegExp and String. Other objects are "host objects", defined not by the language, but by the runtime environment. For example, in a browser, typical host objects belong to the DOM (window, form, links, etc.).
Creating objects
Objects can be created using a constructor or an object literal. The constructor can use either a built-in Object function or a custom function. It is a convention that constructor functions are given a name that starts with a capital letter:
This is the basis for JSON, which is a simple notation that uses JavaScript-like syntax for data exchange.
Methods
A method is simply a function that has been assigned to a property name of an object. Unlike many object-oriented languages, there is no distinction between a function definition and a method definition in object-related JavaScript. Rather, the distinction occurs during function calling; a function can be called as a method.
When called as a method, the standard local variablejQuery do unusual things with ;}functionFoo(yz){this.prefix="a-";if(yz>0){this.pyz=function(){returnthis.prefix+"Y";};}else{this.pyz=function(){returnthis.prefix+"Z";};}this.m1=px;returnthis;}constfoo1=newFoo(1);constfoo2=newFoo(0);foo2.prefix="b-";console.log("foo1/2 "+foo1.pyz()+foo2.pyz());// foo1/2 a-Y b-Zfoo1.m3=px;// Assigns the function itself, not its evaluated result, i.e. not px()constbaz={"prefix":"c-"};baz.m4=px;// No need for a constructor to make an object.console.log("m1/m3/m4 "+foo1.m1()+foo1.m3()+baz.m4());// m1/m3/m4 a-X a-X c-Xfoo1.m2();// Throws an exception, because foo1.m2 does not exist.
Constructors
Constructor functions simply assign values to slots of a newly created object. The values may be data or other functions.
Example: Manipulating an object:
The constructor itself is referenced in the object's prototype's constructor slot. So,
Object deletion is rarely used as the scripting engine will garbage collect objects that are no longer being referenced.
Inheritance
JavaScript supports inheritance hierarchies through prototyping in the manner of Self.
In the following example, the );};this.aBaseFunction=function(){console.log("Base::aBaseFunction()");};}functionDerived(){this.anOverride=function(){console.log("Derived::anOverride()");};}constbase=newBase();Derived.prototype=base;// Must be before new Derived()Derived.prototype.constructor=Derived;// Required to make `instanceof` workconstd=newDerived();// Copies Derived.prototype to d instance's hidden prototype slot.dinstanceofDerived;// truedinstanceofBase;// truebase.aBaseFunction=function(){console.log("Base::aNEWBaseFunction()");};d.anOverride();// Derived::anOverride()d.aBaseFunction();// Base::aNEWBaseFunction()console.log(d.aBaseFunction==Derived.prototype.aBaseFunction);// trueconsole.log(d.__proto__==base);// true in Mozilla-based implementations and false in many others.
The following shows clearly how references to prototypes are copied on instance creation, but that changes to a prototype can affect all instances that refer to it.
In practice many variations of these themes are used, and it can be both powerful and confusing.
Exception handling
JavaScript includes a try ... catch ... finallyexception handling statement to handle run-time errors.
The try ... catch ... finally statement catches exceptions resulting from an error or a throw statement. Its syntax is as follows:
In a browser, the +eval("x + 2"));...})();val9undefined
TypeScript-specific features
TypeScript, a superset of JavaScript developed by Microsoft, adds the following syntax extensions to JavaScript:
- Type signatures (annotations) and compile-timetype checking
- Type inference
- Interfaces
- Enumerated types
- Generics
- Namespaces
- Tuples
- Explicit resource management
Syntactically, TypeScript is very similar to JScript .NET, another Microsoft implementation of the ECMA-262 language standard that added support for static typing and classical object-oriented language features such as classes, inheritance, interfaces, and namespaces. Other inspirations include Java and C#.
Type annotations
TypeScript provides static typing through type annotations to enable type checking at compile time.
Number, Boolean, etc.), which cannot have operations performed from values directly (a Number and number cannot be added). There are additionally undefined and null types for their respective values.All other non-primitive types are annotated using their class name, such as Error. Arrays can be written in two different ways which are both syntactically the same: the generic-based syntax Array<T> and a shorthand with T[].
Additional built-in data types are tuples, unions, never, unknown, void, and any:
- An array with predefined data types at each index is a tuple, represented as
[type1, type2, ..., typeN]. - A variable that can hold more than one type of data is a union, represented using the logical OR
|symbol (string | number). - The
nevertype is used when a given type should be impossible to create, which is useful for filtering mapped types. - The
unknowntype is used when dealing with data of an unpredictable shape. Unlikeany, anunknown-typed variable will throw compilation errors when attempting to access properties or methods on that variable without first narrowing the type to something known. This type is often used for catching Errors, handling API responses, or user input. - The
voidtype is used to represent the lack of a type, e.g. from a function with noreturnstatement. - A value of type
anysupports the same operations as a value in JavaScript and minimal static type checking is performed, which makes it suitable for weakly or dynamically typed structures. This is generally discouraged practice and should be avoided when possible.
Type annotations can be exported to a separate declarations file to make type information available for TypeScript scripts using types already compiled into JavaScript. Annotations can be declared for an existing JavaScript library, as has been done for Node.js and jQuery.
The TypeScript compiler makes use of type inference when types are not given. For example, the add method in the code above would be inferred as returning a number even if no return type annotation had been provided. This is based on the static types of left and right being numbers, and the compiler's knowledge that the result of adding two numbers is always a number.
If no type can be inferred because of lack of declarations (such as in a JavaScript module without types), then it defaults to the dynamic any type. Additional module types can be provided using a .d.ts declaration file using the declare module "moduleName" syntax.
Declaration files
When a TypeScript script gets compiled, there is an option to generate a declaration file (with the extension .d.ts) that functions as an interface to the components in the compiled JavaScript. In the process, the compiler strips away all function and method bodies and preserves only the signatures of the types that are exported. The resulting declaration file can then be used to describe the exported virtual TypeScript types of a JavaScript library or module when a third-party developer consumes it from TypeScript.
The concept of declaration files is analogous to the concept of header files found in C/C++.
instanceof comparison for complex data types. Types with overlapping usage (e.g. a slice method exists on both strings and arrays, the plus operator works on both strings and numbers) don't need additional narrowing to use these features.Enumerated types
Resource management
Although TypeScript does not have manual memory management, it has resource management similar to using-with-resource blocks in C# or try-with-resources blocks in Java, or C++resource acquisition is initialization, that automatically close resources without need for finally blocks. In TypeScript, to automatically close an object, it must implement a global interface Disposable, and implement a method Symbol.dispose(). This will automatically be called at the end of scope.