Le matériel, dont nous publions la traduction aujourd'hui, est dédié aux bases de JavaScript et est destiné aux programmeurs débutants. Il peut être considéré comme une petite référence aux constructions de base de JS. Ici, en particulier, nous parlerons du système de type de données, des variables, des tableaux, des fonctions, des prototypes d'objets et de certaines autres caractéristiques du langage.

Types de données primitifs
Les types de données primitifs suivants sont disponibles en JavaScript:
number
,
boolean
,
string
,
undefined
,
null
. Il convient de noter tout de suite que, lorsque vous travaillez avec des types de données primitifs, par exemple, avec des littéraux de chaîne, nous, même sans effectuer une conversion explicite, serons en mesure d'accéder à leurs méthodes et propriétés. Le point ici est que lorsque vous essayez d'effectuer de telles opérations, les littéraux sont automatiquement équipés du wrapper d'objet approprié.
▍ Numéros
JavaScript n'a qu'un seul type de nombre - ce sont les nombres à virgule flottante double précision. Cela conduit au fait que les résultats du calcul de certaines expressions sont arithmétiquement incorrects. Vous savez peut-être déjà qu'en JS la valeur de l'expression
0.1 + 0.2
pas
0.3
. En même temps, lorsque vous travaillez avec des entiers, de tels problèmes ne sont pas observés, c'est-à-dire
1 + 2 === 3
.
JavaScript a un objet
Number
, qui est un wrapper d'objet pour les valeurs numériques. Les objets de type
Number
peuvent être créés soit à l'aide d'une commande de la forme
var a = new Number(10)
, soit vous pouvez compter sur le comportement automatique du système décrit ci-dessus. Cela, en particulier, vous permet d'appeler des méthodes stockées dans
Number.prototype
telles
Number.prototype
sont appliquées aux littéraux numériques:
(123).toString(); //"123" (1.23).toFixed(1); //"1.2"
Il existe des fonctions globales conçues pour convertir les valeurs d'autres types en type numérique. C'est
parseInt()
,
parseFloat()
et la construction
Number()
, qui dans ce cas agit comme une fonction normale qui effectue la conversion de type:
parseInt("1") //1 parseInt("text") //NaN parseFloat("1.234") //1.234 Number("1") //1 Number("1.234") //1.234
Si, au cours de l'opération avec des nombres, quelque chose est obtenu qui n'est pas un nombre (lors de certains calculs ou lorsque vous essayez de convertir quelque chose en nombre), JavaScript ne générera pas d'erreur, mais présentera le résultat d'une telle opération comme la valeur
NaN
(Not-a-Number, pas un nombre). Afin de vérifier si une certaine valeur est
NaN
, vous pouvez utiliser la fonction
isNaN()
.
Les opérations arithmétiques JS fonctionnent de manière assez familière, mais vous devez faire attention au fait que l'opérateur
+
peut effectuer l'ajout de nombres et la concaténation de chaînes.
1 + 1 //2 "1" + "1" //"11" 1 + "1" //"11"
▍Chaînes
Les chaînes JavaScript sont des chaînes de caractères Unicode. Les littéraux de chaîne sont créés en entourant le texte à placer entre guillemets doubles (
""
) ou simples (
''
). Comme déjà mentionné, lorsque nous travaillons avec des littéraux de chaîne, nous pouvons compter sur l'encapsuleur d'objet correspondant, dont le prototype a de nombreuses méthodes utiles, parmi lesquelles
substring()
,
indexOf()
,
concat()
.
"text".substring(1,3) //ex "text".indexOf('x') //2 "text".concat(" end") //text end
Les chaînes, comme les autres valeurs primitives, sont immuables. Par exemple, la méthode
concat()
ne modifie pas une chaîne existante, mais en crée une nouvelle.
▍Valeurs logiques
Le type de données logique dans JS est représenté par deux valeurs -
true
et
false
. Le langage peut convertir automatiquement diverses valeurs en un type de données logique. Ainsi, false, en plus de la valeur logique
false
, sont les valeurs
null
,
undefined
,
''
(chaîne vide),
0
et
NaN
. Tout le reste, y compris les objets, représente de véritables significations. Au cours des opérations logiques, tout ce qui est considéré comme vrai est converti en
true
et tout ce qui est considéré comme faux est converti en
false
. Jetez un œil à l'exemple suivant. Conformément aux principes ci-dessus, une chaîne vide sera convertie en
false
et à la suite de cette exécution de code, la chaîne
This is false
arrivera à la console.
let text = ''; if(text) { console.log("This is true"); } else { console.log("This is false"); }
Les objets
Les objets sont des structures dynamiques constituées de paires clé-valeur. Les valeurs peuvent avoir des types de données primitifs, peuvent être des objets ou des fonctions.
Les objets sont plus faciles à créer à l'aide de la syntaxe littérale de l'objet:
let obj = { message : "A message", doSomething : function() {} }
Les propriétés d'un objet peuvent être lues, ajoutées, modifiées et supprimées à tout moment. Voici comment procéder:
- Propriétés de lecture:
object.name, object[expression]
. - Écriture de données dans les propriétés (si la propriété en cours d'accès n'existe pas, une nouvelle propriété avec la clé spécifiée est ajoutée):
object.name = value
, object[expression] = value
. - Suppression de propriétés:
delete object.name
, delete object[expression]
.
Voici quelques exemples:
let obj = {}; // obj.message = "A message"; // obj.message = "A new message"; // delete object.message; //
Les objets du langage sont implémentés sous forme de tables de hachage. Une simple table de hachage peut être créée à l'aide de la commande
Object.create(null)
:
let french = Object.create(null); french["yes"] = "oui"; french["no"] = "non"; french["yes"];//"oui"
Si l'objet doit être rendu immuable, vous pouvez utiliser la commande
Object.freeze()
.
Pour parcourir toutes les propriétés d'un objet, vous pouvez utiliser la commande
Object.keys()
:
function logProperty(name){ console.log(name); // console.log(obj[name]); // } Object.keys(obj).forEach(logProperty);
▍Comparaison des valeurs des types et objets primitifs
Dans le travail pratique avec des valeurs primitives, vous pouvez, comme déjà mentionné, les percevoir comme des objets qui ont des propriétés et des méthodes, bien qu'ils ne soient pas des objets. Les valeurs primitives sont immuables, la structure interne des objets peut changer.
Variables
En JavaScript, les variables peuvent être déclarées à l'aide des mots clés
var
,
let
et
const
.
En utilisant le mot-clé
var
, vous pouvez déclarer une variable et, si nécessaire, l'initialiser avec une certaine valeur. Si la variable n'est pas initialisée, sa valeur n'est
undefined
. Les variables déclarées à l'aide du mot clé
var
ont une portée fonctionnelle.
Le mot clé
let
est très similaire à
var
, la différence est que les variables déclarées avec le mot clé
let
ont une portée de bloc.
Les variables déclarées à l'aide du mot clé
const
ont également une portée de bloc qui, étant donné que les valeurs de ces variables ne peuvent pas être modifiées, sera plus correctement appelée «constantes». Le mot-clé
const
, qui «fige» la valeur d'une variable déclarée en l'utilisant, peut être comparé à la méthode
Object.freeze()
, qui «fige» les objets.
Si une variable est déclarée en dehors d'une fonction, sa portée est globale.
Tableaux
Les tableaux en JavaScript sont implémentés à l'aide d'objets. Par conséquent, lorsque nous parlons de tableaux, nous discutons en fait d'objets similaires aux tableaux. Vous pouvez travailler avec des éléments de tableau à l'aide de leurs indices. Les indices numériques sont convertis en chaînes et utilisés comme noms pour accéder aux valeurs des éléments du tableau. Par exemple, une construction de la forme
arr[1]
similaire à une construction de la forme
arr['1']
, et les deux donneront accès à la même valeur:
arr[1] === arr['1']
. Conformément à ce qui précède, un tableau simple déclaré par la commande
let arr = ['A', 'B', 'C']
est représenté comme un objet de la forme suivante:
{ '0': 'A', '1': 'B', '2': 'C' }
La suppression d'éléments de tableau à l'aide de la commande de
delete
laisse des trous. Pour éviter ce problème, vous pouvez utiliser la commande
splice()
, mais elle fonctionne lentement, car, après la suppression d'un élément, elle déplace les éléments restants du tableau, les décalant en fait au début du tableau, vers la gauche.
let arr = ['A', 'B', 'C']; delete arr[1]; console.log(arr); // ['A', empty, 'C'] console.log(arr.length); // 3
Les méthodes de tableau facilitent l'implémentation de structures de données telles que les piles et les files d'attente:
// let stack = []; stack.push(1); // [1] stack.push(2); // [1, 2] let last = stack.pop(); // [1] console.log(last); // 2 // let queue = []; queue.push(1); // [1] queue.push(2); // [1, 2] let first = queue.shift();//[2] console.log(first); // 1
Les fonctions
Les fonctions en JavaScript sont des objets. Les fonctions peuvent être attribuées à des variables, stockées dans des objets ou des tableaux, transmises en tant qu'arguments à d'autres fonctions et renvoyées par d'autres fonctions.
Il existe trois façons de déclarer des fonctions:
- Déclaration de fonction classique (déclaration de fonction ou déclaration de fonction).
- L'utilisation d'expressions fonctionnelles (Function Expression), également appelées littéraux fonctionnels (Function Literal).
- Utilisation de la syntaxe des fonctions fléchées (fonction flèche).
▍ Déclaration de fonction classique
Avec cette approche de déclaration de fonctions, les règles suivantes s'appliquent:
- La fonction est le premier mot-clé d'une ligne de déclaration de
function
. - Un nom doit être attribué aux fonctions.
- La fonction peut être utilisée dans le code avant sa déclaration en raison du mécanisme qui place la déclaration de la fonction au sommet de la portée dans laquelle elle est déclarée.
Voici à quoi ressemble une déclaration de fonction classique:
function doSomething(){}
▍ Expressions fonctionnelles
Lors de l'utilisation d'expressions fonctionnelles, les éléments suivants doivent être pris en compte:
- Le mot clé de
function
n'est plus le premier mot d'une ligne de déclaration de fonction. - Un nom de fonction est facultatif. Il est possible d'utiliser à la fois des expressions fonctionnelles anonymes et nommées.
- Les commandes pour appeler de telles fonctions doivent suivre les commandes pour leur déclaration.
- Une telle fonction peut être lancée immédiatement après la déclaration en utilisant la syntaxe de IIFE (Immediateely Invoked Function Expression - immédiatement appelée expression de fonction).
L'expression fonctionnelle ressemble à ceci:
let doSomething = function() {}
▍ Fonctions flèches
Les fonctions fléchées, en fait, peuvent être considérées comme du «sucre syntaxique» pour créer des expressions fonctionnelles anonymes. Il convient de noter que ces fonctions n'ont pas leurs propres entités
this
et
arguments
. La déclaration de la fonction flèche ressemble à ceci:
let doSomething = () = > {};
▍ Façons d'appeler des fonctions
Les fonctions peuvent être appelées de différentes manières.
Appel de fonction normale
doSomething(arguments)
Appel de fonction sous la forme d'une méthode objet
theObject.doSomething(arguments) theObject["doSomething"](arguments)
Appel de fonction constructeur
new doSomething(arguments)
Appel d'une fonction à l'aide de la méthode apply ()
doSomething.apply(theObject, [arguments]) doSomething.call(theObject, arguments)
Appel d'une fonction à l'aide de la méthode bind ()
let doSomethingWithObject = doSomething.bind(theObject); doSomethingWithObject();
Les fonctions peuvent être appelées avec plus ou moins d'arguments que le nombre de paramètres spécifiés lors de leur déclaration. Au cours du travail de la fonction, les arguments "supplémentaires" seront simplement ignorés (bien que la fonction y aura accès), les paramètres manquants obtiendront la valeur
undefined
.
Les fonctions ont deux pseudo-paramètres:
this
et
arguments
.
▍ Mot-clé ceci
Le
this
représente le contexte d'une fonction. La valeur qu'il pointe dépend de la façon dont la fonction a été appelée. Voici les significations du mot
this
clé
this
fonction de la façon dont la fonction est appelée (elles sont décrites ci-dessus avec des exemples de code, dont les constructions sont utilisées ici):
- L'appel de fonction habituel est
window
/ undefined
. - Un appel de fonction sous la forme d'une méthode objet est
theObject
. - Un appel de fonction sous la forme d'un constructeur est un nouvel objet.
- Appel d'une fonction à l'aide de la méthode
apply()
- theObject
. - Appel d'une fonction à l'aide de la méthode
bind()
- theObject
.
▍ Arguments des mots clés
Le mot-clé
arguments
est un pseudo-paramètre qui donne accès à tous les arguments utilisés pour appeler la fonction. Il ressemble à un tableau, mais pas à un tableau. En particulier, il n'a pas de méthodes de tableau.
function reduceToSum(total, value){ return total + value; } function sum(){ let args = Array.prototype.slice.call(arguments); return args.reduce(reduceToSum, 0); } sum(1,2,3);
Une alternative au mot-clé
arguments
est la nouvelle syntaxe pour les paramètres restants. Dans l'exemple suivant,
args
est un tableau contenant tout ce qui a été transmis à la fonction lors de son appel.
function sum(...args){ return args.reduce(reduceToSum, 0); }
ReturnRetour opérateur
Une fonction qui n'a pas de
return
retour renverra
undefined
. En utilisant le mot-clé
return
, faites attention au fonctionnement du mécanisme d'insertion automatique des points-virgules. Par exemple, la fonction suivante renverra non pas un objet vide, mais une valeur
undefined
:
function getObject(){ return { } } getObject()
Afin d'éviter un problème similaire, le crochet ouvrant doit être placé sur la même ligne que la
return
:
function getObject(){ return { } }
Typage dynamique
JavaScript est un langage de frappe dynamique. Cela signifie que des valeurs spécifiques ont des types, mais pas des variables. Pendant l'exécution du programme, des valeurs de différents types peuvent être écrites dans la même variable. Voici un exemple de fonction qui fonctionne avec des valeurs de différents types:
function log(value){ console.log(value); } log(1); log("text"); log({message : "text"});
Pour connaître le type de données stockées dans une variable, vous pouvez utiliser l'opérateur
typeof()
:
let n = 1; typeof(n); //number let s = "text"; typeof(s); //string let fn = function() {}; typeof(fn); //function
Modèle d'exécution monothread
Le runtime JavaScript est monothread. Cela s'exprime notamment par l'impossibilité d'exécuter simultanément deux fonctions (si l'on ne tient pas compte des possibilités d'exécution de code asynchrone, que nous n'abordons pas ici). Le runtime a une soi-disant file d'attente d'événements, qui stocke une liste de tâches qui doivent être traitées. Par conséquent, pour un schéma d'exécution JS à un seul thread, le problème des verrous de ressources mutuelles n'est pas typique, par conséquent, le mécanisme de verrouillage n'est pas nécessaire ici. Cependant, le code entrant dans la file d'attente d'événements doit s'exécuter rapidement. En cas de surcharge de travail, dans l'application du navigateur, le thread principal, la page de l'application ne répondra pas aux actions de l'utilisateur et le navigateur proposera de fermer cette page.
Gestion des exceptions
JavaScript dispose d'un mécanisme de gestion des exceptions. Il fonctionne selon un principe assez habituel pour de tels mécanismes: le code qui peut provoquer une erreur est exécuté à l'aide de la construction
try/catch
. Le code lui-même est dans le bloc
try
, les erreurs sont traitées dans le
catch
.
Il est intéressant de noter que parfois JavaScript, en cas d'urgence, ne produit pas de messages d'erreur. Cela est dû au fait que JS n'a commis aucune erreur avant l'adoption de la norme ECMAScript 3.
Par exemple, dans le fragment de code suivant, une tentative de modification d'un objet «figé» échouera, mais aucune exception ne sera levée.
let obj = Object.freeze({}); obj.message = "text";
Certaines des erreurs JS "silencieuses" apparaissent en mode strict, vous pouvez l'activer en utilisant la construction
"use strict";
.
Système prototype
La base de ces mécanismes JS comme les fonctions constructeurs, la commande
Object.create()
, le mot
class
clé
class
, est basée sur un système prototype.
Prenons l'exemple suivant:
let service = { doSomething : function() {} } let specializedService = Object.create(service); console.log(specializedService.__proto__ === service);
Ici, pour créer un objet
Object.create()
, dont le prototype était de créer un objet de
service
, la commande
Object.create()
été utilisée. En conséquence, il s'avère que la méthode
doSomething()
peut être appelée en accédant à l'objet
doSomething()
. En outre, cela signifie que la propriété
__proto__
de l'objet
specializedService
pointe vers un objet de
service
.
Créez maintenant un objet similaire en utilisant le mot
class
clé
class
:
class Service { doSomething(){} } class SpecializedService extends Service { } let specializedService = new SpecializedService(); console.log(specializedService.__proto__ === SpecializedService.prototype);
Les méthodes déclarées dans la classe
Service
seront ajoutées à l'objet
Service.prototype
. Les instances de la classe
Service
auront le même prototype (
Service.prototype
). Toutes les instances délégueront des appels de méthode à l'objet
Service.prototype
. Par conséquent, il s'avère que les méthodes ne sont déclarées qu'une seule fois, dans
Service.prototype
, après quoi elles sont "héritées" par toutes les instances de la classe.
▍ Chaîne prototype
Les objets peuvent être «héritiers» d'autres objets. Chaque objet possède un prototype dont les méthodes sont à sa disposition. Si vous essayez d'accéder à une propriété qui n'est pas dans l'objet lui-même, JavaScript commencera à la rechercher dans la chaîne de prototypes. Ce processus se poursuivra jusqu'à ce que la propriété soit trouvée ou jusqu'à ce que la recherche atteigne la fin de la chaîne.
À propos de la programmation fonctionnelle en JavaScript
En JavaScript, les fonctions sont des objets de première classe; le langage prend en charge le mécanisme de fermeture. Cela ouvre la voie à l'implémentation de techniques de programmation fonctionnelle dans JS. En particulier, nous parlons de la possibilité d'utiliser des fonctions d'ordre supérieur.
Une fermeture est une fonction interne qui a accès aux variables déclarées à l'intérieur de la fonction parent, même après l'exécution de la fonction parent.
Une fonction d'ordre supérieur est une fonction qui peut prendre d'autres fonctions comme arguments, renvoyer des fonctions ou faire les deux.
La programmation fonctionnelle dans JS est couverte dans de nombreuses publications. Si vous êtes intéressé, voici quelques documents sur ce sujet consacrés
aux fonctions de première classe , à la
composition , aux
décorateurs , aux
fermetures et à la
lisibilité du code écrit dans un style fonctionnel.
Résumé
La puissance de JavaScript réside dans sa simplicité. La compréhension des mécanismes de base du langage permet au programmeur utilisant JS d'appliquer plus efficacement ces mécanismes et jette les bases de sa croissance professionnelle.
Chers lecteurs! Selon vous, quelles sont les caractéristiques de JavaScript que la plupart des débutants provoquent?
