Maison > interface Web > js tutoriel > Démystifier JavaScript : comprendre les contextes d'exécution, le levage et la conversion de type

Démystifier JavaScript : comprendre les contextes d'exécution, le levage et la conversion de type

DDD
Libérer: 2024-10-11 20:58:02
original
1003 Les gens l'ont consulté

JavaScript peut sembler simple en surface, mais sous le capot, il se passe beaucoup de choses. Aujourd'hui, nous allons explorer certains concepts essentiels tels que les contextes d'exécution, le levage, les types de données primitifs et non primitifs et la conversion de type. Il est essentiel de les comprendre si vous souhaitez écrire un code meilleur et sans bug.

Demystifying JavaScript: Understanding Execution Contexts, Hoisting, and Type Conversion

Contexte global d'exécution et environnement lexical
Lorsque vous exécutez un fichier JavaScript dans le navigateur, le code est exécuté ligne par ligne dans la pile d'appels. Cependant, avant l'exécution de votre code, un contexte d'exécution global est créé. Ce contexte configure les objets this et window. Dans Node.js, l'équivalent de window est global, et si vous comparez les deux, vous constaterez que window === global renvoie true.

Chaque fois que vous appelez une fonction, un nouvel environnement lexical est créé. Le contexte d'exécution global est le premier à être créé, et toutes les fonctions définies à l'intérieur peuvent accéder à ses variables. C'est ainsi que fonctionne la chaîne de portée de JavaScript : vous pouvez accéder aux variables dans la portée externe (globale) depuis l'intérieur d'une fonction.

Levage : Variables et fonctions
JavaScript dispose d'un mécanisme appelé levage, dans lequel les variables et les fonctions sont « déplacées » vers le haut de leur portée lors de la compilation. Voici comment cela fonctionne :

Variables : les variables déclarées avec var sont partiellement levées, ce qui signifie que vous pouvez les référencer avant qu'elles ne soient initialisées, mais leur valeur sera indéfinie jusqu'à ce que la ligne où elles sont initialisées soit atteinte.
Fonctions : les fonctions déclarées avec la syntaxe de déclaration de fonction sont entièrement hissées, ce qui signifie que vous pouvez appeler la fonction avant même sa déclaration dans le code.
Exemple :

console.log(a); // undefined
var a = 5;

console.log(b); // Error: b is not defined
let b = 10;

hoistedFunction(); // Works!
function hoistedFunction() {
  console.log('This function is hoisted!');
}

notHoistedFunction(); // Error: notHoistedFunction is not a function
var notHoistedFunction = function() {
  console.log('This function is not hoisted!');
}
Copier après la connexion

Comme vous pouvez le voir, let et const ne sont pas hissés comme var, et les expressions de fonction (comme notHoistedFunction) ne sont définies qu'au moment de l'exécution.

Types primitifs et non primitifs
JavaScript a deux types de données : primitives et non primitives.

Les types primitifs incluent chaîne, nombre, booléen, non défini, nul, symbole et bigint. Ceux-ci sont immuables, ce qui signifie que leurs valeurs ne peuvent pas être modifiées. Par exemple :

let x = 'hello';
x[0] = 'H'; // This won’t change the string, it stays 'hello'
Copier après la connexion

Les types non primitifs sont des objets, des tableaux et des fonctions. Ceux-ci sont mutables et leurs valeurs peuvent être modifiées car elles sont transmises par référence. Par exemple :

let obj1 = { name: 'John' };
let obj2 = obj1; // Both obj1 and obj2 now reference the same object
obj2.name = 'Doe';
console.log(obj1.name); // Outputs: Doe
Copier après la connexion

Pour éviter de modifier l'objet original, vous pouvez créer une copie superficielle en utilisant Object.assign() ou l'opérateur spread (...). Pour les copies complètes, qui copient des objets imbriqués, utilisez JSON.parse() et JSON.stringify().

Exemple d'extrait de code : copie superficielle ou copie approfondie

// Shallow copy example
let obj1 = { name: 'John', details: { age: 30 } };
let obj2 = { ...obj1 }; // Shallow copy
obj2.details.age = 40;
console.log(obj1.details.age); // Output: 40 (Shallow copy affects the original)

// Deep copy example
let obj3 = JSON.parse(JSON.stringify(obj1)); // Deep copy
obj3.details.age = 50;
console.log(obj1.details.age); // Output: 40 (Deep copy doesn’t affect the original)
Copier après la connexion

Conversion et comparaison de types
JavaScript est un langage typé dynamiquement, ce qui signifie que vous n'avez pas besoin de spécifier explicitement les types de variables. Cependant, cela peut parfois conduire à un comportement inattendu, notamment lors de l'utilisation d'opérateurs de comparaison.

Préférez toujours utiliser des triples égaux (===) plutôt que des doubles égaux (==) pour éviter la coercition de type. Par exemple :

console.log(0 == '0'); // true (type coercion happens)
console.log(0 === '0'); // false (no type coercion)
Copier après la connexion

Pour les cas particuliers, comme comparer NaN, utilisez Object.is() car NaN === NaN renvoie false.

console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
Copier après la connexion

Runtime de JavaScript et Node.js
JavaScript s'exécute sur un environnement d'exécution synchrone à thread unique, ce qui signifie qu'il ne peut exécuter qu'une seule tâche à la fois. Cela peut sembler limitant, mais JavaScript gère efficacement les tâches asynchrones en utilisant l'API Web et la file d'attente de rappel. Voici comment cela fonctionne :

Lorsque JavaScript rencontre une tâche asynchrone (comme setTimeout ou une requête HTTP), il envoie la tâche à l'API Web.
La pile d'appels continue d'exécuter le code restant.
Une fois la tâche asynchrone terminée, elle est ajoutée à la file d'attente de rappel et s'exécutera lorsque la pile d'appels sera vide.
Node.js étend ce runtime côté serveur, en utilisant le moteur V8 et un système d'E/S non bloquant alimenté par libuv. Node.js a introduit l'idée d'une boucle d'événements à thread unique capable de gérer plusieurs requêtes sans bloquer d'autres opérations.

En comprenant comment JavaScript gère les contextes d'exécution, le levage, la conversion de type et les tâches asynchrones, vous serez en mesure d'écrire du code plus propre et plus efficace. Grâce à la nature dynamique de JavaScript, des outils tels que TypeScript peuvent vous aider à éviter les pièges courants en fournissant des vérifications de type statiques qui préparent votre code à la production.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal