Le livre «JavaScript expressif. Programmation web moderne. 3e édition

image Salut, habrozhiteli! Ce livre vous permettra d'approfondir le sujet, d'apprendre à écrire du code beau et efficace. Vous découvrirez la syntaxe, les fonctions fléchées et asynchrones, l'itérateur, les chaînes de modèle et la portée du bloc.

Marein Haverbeke - praticienne. Acquérir de l'expérience et apprendre la langue à travers une multitude d'exemples à travers des exercices et des projets de formation. Tout d'abord, vous vous familiariserez avec la structure du langage JavaScript, la gestion des structures, des fonctions et des structures de données, puis étudierez la gestion des erreurs et la correction des bogues, la modularité et la programmation asynchrone, puis passez à la programmation du navigateur.

Donnez votre avis sur ce livre


Ce livre est divisé en trois grandes parties. Les 12 premiers chapitres traitent du langage JavaScript. Les sept chapitres suivants traitent des navigateurs et de la façon dont JavaScript est utilisé pour les programmer. Enfin, deux chapitres sont consacrés à Node.js, un autre environnement de programmation JavaScript.

Tout au long du livre, vous rencontrerez cinq chapitres de projets qui décrivent de plus grands exemples de programmes afin que vous puissiez ressentir le goût d'une vraie programmation. Dans l'ordre de leur apparition, nous travaillerons à la création d'un robot de livraison, d'un langage de programmation, d'une plateforme de jeu, d'un éditeur graphique raster et d'un site dynamique.

La partie linguistique du livre commence par quatre chapitres qui vous présenteront la structure de base du langage JavaScript. Vous en apprendrez plus sur les structures de contrôle (comme le mot-clé while, que vous avez déjà vu dans l'introduction), les fonctions (écrire vos propres blocs de construction) et les structures de données. Après cela, vous pouvez écrire les programmes les plus simples. De plus, les chapitres 5 et 6 décrivent comment utiliser les fonctions et les objets pour écrire du code plus abstrait et contrôler sa complexité.

Après le chapitre du premier projet, la partie linguistique du livre sera poursuivie - les chapitres suivants sont consacrés à la détection et à la correction des erreurs, aux expressions régulières (un outil important pour travailler avec du texte), à ​​la modularité (une autre défense contre la complexité) et à la programmation asynchrone (travailler avec des événements qui durent pour certains temps). La première partie du livre complète le chapitre du deuxième projet.

La deuxième partie, les chapitres 13 à 19, décrit les outils auxquels un navigateur compatible JavaScript a accès. Vous apprendrez à afficher des éléments à l'écran (chapitres 14 et 17), à répondre aux entrées de l'utilisateur (chapitre 15) et à les partager sur le réseau (chapitre 18). Cette partie contient également deux chapitres de projets.

Après cela, Node.js est décrit au chapitre 20 et un petit site est créé au chapitre 21 à l'aide de cet outil.

Extrait. Sommation avec réduction


Une autre chose courante qui est souvent effectuée avec les tableaux est de calculer une valeur unique en fonction d'eux. Un cas particulier de ceci est l'exemple que nous avons déjà utilisé avec la sommation d'un ensemble de nombres. Un autre exemple est de trouver la police contenant le plus de caractères.

Une opération d'ordre supérieur qui implémente ce modèle est appelée raccourci (parfois aussi appelée convolution). Cette opération crée la valeur en récupérant à plusieurs reprises un élément du tableau et en le combinant avec la valeur actuelle. Lors de la sommation des nombres, nous partons de zéro, puis ajoutons chaque élément suivant à la somme.

Les paramètres de la fonction de réduction, en plus du tableau, sont une fonction de combinaison et une valeur initiale. Cette fonction est un peu plus compliquée que le filtre et la carte, alors regardez-la de plus près:

function reduce(array, combine, start) { let current = start; for (let element of array) { current = combine(current, element); } return current; } console.log(reduce([1, 2, 3, 4], (a, b) => a + b, 0)); // → 10 

La méthode standard pour travailler avec des tableaux réduits, qui, bien sûr, correspond à cette fonction, présente une commodité supplémentaire. Si le tableau contient au moins un élément, vous pouvez omettre l'argument de début. La méthode sélectionne le premier élément du tableau comme valeur initiale et démarre la réduction à partir du deuxième élément.

 console.log([1, 2, 3, 4].reduce((a, b) => a + b)); // → 10 

Pour utiliser réduire (deux fois) pour trouver la police avec le plus de caractères, nous pouvons écrire quelque chose comme ceci:

 function characterCount(script) { return script.ranges.reduce((count, [from, to]) => { return count + (to — from); }, 0); } console.log(SCRIPTS.reduce((a, b) => { return characterCount(a) < characterCount(b) ? b : a; })); // → {name: "Han", ...} 

La fonction characterCount réduit les plages affectées à cette police en calculant la somme de leurs tailles. Faites attention à l'utilisation de la déstructuration dans la liste des paramètres de la fonction de réduction. Ensuite, le deuxième appel à réduire utilise le résultat précédent pour rechercher la police la plus grande, en comparant à plusieurs reprises les deux polices et en renvoyant la plus grande.

La police Han a plus de 89 000 caractères qui lui sont attribués dans la norme Unicode, ce qui en fait le plus grand système d'écriture de notre ensemble de données. Han est une police parfois utilisée pour les textes chinois, japonais et coréens. Leurs langues ont de nombreux caractères communs, bien qu'elles soient écrites différemment. Le Consortium Unicode (situé aux États-Unis) a décidé de considérer ces caractères comme un système d'enregistrement unique afin de sauvegarder les codes de caractères. Cela s'appelle Han Unification et est toujours très ennuyeux pour certaines personnes.

Composabilité


Réfléchissons: comment pourrions-nous réécrire l'exemple précédent (trouver la plus grande police) sans fonctions d'ordre supérieur? Le code suivant n'est pas bien pire.

 let biggest = null; for (let script of SCRIPTS) { if (biggest == null || characterCount(biggest) < characterCount(script)) { biggest = script; } } console.log(biggest); // → {name: "Han", ...} 

Plusieurs liaisons supplémentaires sont apparues et le programme est devenu quatre lignes plus longues. Mais ce code est encore assez clair.

Les fonctions d'ordre supérieur commencent à être vraiment utiles lorsque vous devez composer des opérations. À titre d'exemple, nous allons écrire un code qui calcule l'année moyenne de création de polices de langues vivantes et mortes dans un ensemble de données.

 function average(array) { return array.reduce((a, b) => a + b) / array.length; } console.log(Math.round(average( SCRIPTS.filter(s => s.living).map(s => s.year)))); // → 1188 console.log(Math.round(average( SCRIPTS.filter(s => !s.living).map(s => s.year)))); // → 188 

Ainsi, les scripts de langues mortes dans Unicode sont en moyenne plus anciens que les scripts de langues vivantes.

Ce ne sont pas des statistiques particulièrement importantes ou surprenantes. J'espère cependant que le code utilisé pour le calculer est facile à lire. Cela peut être imaginé comme un convoyeur: nous commençons par analyser toutes les polices, filtrer les vivants (ou morts), prendre les années de leur création, calculer la valeur moyenne et arrondir le résultat.

Ce calcul pourrait également être représenté comme un grand cycle.

 let total = 0, count = 0; for (let script of SCRIPTS) { if (script.living) { total += script.year; count += 1; } } console.log(Math.round(total / count)); // → 1188 

Mais dans ce code, il est plus difficile de comprendre quoi et comment est calculé. Et comme les résultats intermédiaires ne sont pas présentés comme des valeurs cohérentes, il faudrait faire beaucoup plus de travail pour séparer quelque chose comme la moyenne dans une fonction distincte.

En termes de ce que l'ordinateur fait réellement, ces deux approches sont également fondamentalement différentes. Le premier crée de nouveaux tableaux lorsque le filtre et la carte sont exécutés, tandis que le second ne calcule que certains nombres, faisant moins de travail. Habituellement, vous pouvez vous permettre une option plus lisible, mais si vous devez traiter de très grands tableaux et le faire plusieurs fois, un style moins abstrait peut vous donner un gain de vitesse supplémentaire.

Chaînes et codes de caractères


Une utilisation des ensembles de données consiste à déterminer dans quelle police un morceau de texte donné est tapé. Regardons un programme qui fait cela.

Rappelez-vous que pour chaque police, il existe un tableau de plages de codes de caractères. Par conséquent, connaissant le code de caractère, nous pourrions utiliser la fonction suivante pour trouver la police correspondante (le cas échéant):

 function characterScript(code) { for (let script of SCRIPTS) { if (script.ranges.some(([from, to]) => { return code >= from && code < to; })) { return script; } } return null; } console.log(characterScript(121)); // → {name: "Latin", ...} 

La méthode some est une autre fonction d'ordre supérieur. Il prend une fonction de test et signale s'il renvoie vrai pour n'importe quel élément du tableau.

Mais comment obtenir les codes de caractères sous forme de chaîne?

Dans le chapitre 1, j'ai mentionné qu'en JavaScript, les chaînes sont représentées comme des séquences de nombres de 16 bits. Ce sont les soi-disant unités de code. Initialement, on supposait qu'en Unicode le code de caractère sera placé dans un tel bloc (ce qui donne un peu plus de 65 000 caractères). Quand il est devenu clair que cela ne suffisait pas, beaucoup ont commencé à s'opposer à la nécessité d'utiliser plus de mémoire pour stocker un caractère. Pour résoudre ce problème, le format UTF-16 utilisé dans les chaînes JavaScript a été inventé. Dans ce document, les caractères les plus courants occupent une unité de code 16 bits, et le reste - deux unités de code.

Aujourd'hui, il est généralement admis que l'UTF-16 était une mauvaise idée. Il semble être créé pour produire des erreurs. Vous pouvez facilement écrire un programme pour lequel les unités de code et les caractères sont identiques. Et si votre langue maternelle n'utilise pas de caractères qui occupent deux unités de code, ce programme fonctionnera correctement. Mais, dès que quelqu'un essaie d'utiliser un tel programme pour un alphabet moins courant, par exemple pour les caractères chinois, il se casse immédiatement. Heureusement, après l'émergence des émoticônes, deux unités de code ont commencé à être utilisées partout pour le codage des caractères, et la charge de résoudre de tels problèmes a été répartie plus équitablement.

Malheureusement, les opérations évidentes avec des chaînes JavaScript, telles que l'obtention de leur longueur via la propriété length et l'accès à leur contenu à l'aide de crochets, ne concernent que les unités de code.

image

La méthode JavaScript charCodeAt ne renvoie pas le code de caractère complet, mais une unité de code. La méthode codePointAt qui apparaît plus tard renvoie le caractère Unicode complet. Nous pourrions donc l'utiliser pour obtenir des caractères d'une chaîne. Mais l'argument passé à codePointAt est toujours un index dans une séquence d'unités de code. Ainsi, afin d'itérer sur tous les caractères d'une chaîne, nous devons encore résoudre la question de savoir si une ou deux unités de code occupent un caractère.

Dans le chapitre précédent, j'ai mentionné que la boucle for / of peut également être utilisée pour les chaînes. Comme codePointAt, ce type de boucle est apparu à un moment où les programmeurs ont clairement compris les problèmes de l'UTF-16. Lorsque vous appliquez cette boucle à une chaîne, elle donne de vrais caractères, pas des unités de code.

image

Si vous avez un caractère (qui est une chaîne d'une ou deux unités de code), pour obtenir son code, vous pouvez utiliser codePointAt (0).

Reconnaissance de texte


Nous avons une fonction characterScript et un moyen d'énumérer correctement les caractères dans une boucle. L'étape suivante consiste à compter le nombre de caractères appartenant à chaque police. Ici, nous avons besoin d'une abstraction de comptage:

 function countBy(items, groupName) { let counts = []; for (let item of items) { let name = groupName(item); let known = counts.findIndex(c => c.name == name); if (known == -1) { counts.push({name, count: 1}); } else { counts[known].count++; } } return counts; } console.log(countBy([1, 2, 3, 4, 5], n => n > 2)); // → [{name: false, count: 2}, {name: true, count: 3}] 

La fonction countBy accepte une collection (tout ce qui peut être trié dans une boucle for / of) et une fonction qui calcule le nom du groupe pour un élément donné. La fonction countBy renvoie un tableau d'objets, chacun contenant le nom du groupe et le nombre d'éléments trouvés pour lui.

Cette fonction utilise une autre méthode de travail avec les tableaux - findIndex. Cette méthode est quelque peu similaire à indexOf, mais au lieu de rechercher une valeur spécifique, elle trouve la première valeur pour laquelle la fonction donnée renvoie true. Si l'élément n'est pas trouvé, findIndex, comme indexOf, renvoie –1.

En utilisant countBy, nous pouvons écrire une fonction qui indique quelles polices ont été utilisées dans ce morceau de texte.

image

La fonction compte d'abord les caractères par nom de police, en utilisant characterScript pour leur donner un nom, et retourne la chaîne «none» pour les caractères qui n'appartiennent à aucune police. L'appel du filtre supprime l'entrée "none" du tableau résultant, car nous ne sommes pas intéressés par ces caractères.

Pour pouvoir calculer des pourcentages, nous devons d'abord obtenir le nombre total de caractères appartenant à la police que nous pouvons calculer en utilisant la méthode de réduction. Si aucun de ces caractères n'est trouvé, la fonction renvoie une chaîne spécifique. Sinon, il convertit les résultats du comptage en chaînes lisibles à l'aide de map, puis les combine à l'aide de join.

Résumé


La possibilité de transmettre des valeurs fonctionnelles à d'autres fonctions est un aspect très utile de JavaScript. Cela vous permet de créer des fonctions qui simulent des calculs avec des espaces. Par la suite, lors de l'appel de telles fonctions dans le code, ces «lacunes» sont remplies de valeurs fonctionnelles.

Pour les tableaux, il existe un certain nombre de méthodes utiles d'ordre supérieur. La méthode forEach peut être utilisée pour parcourir les éléments d'un tableau. La méthode de filtrage renvoie un nouveau tableau contenant uniquement des éléments qui satisfont à la condition de la fonction prédicative. La conversion de tableau en exécutant une fonction pour chaque élément se fait à l'aide de map. Pour combiner tous les éléments d'un tableau en une seule valeur, vous pouvez utiliser réduire. La méthode some vérifie si un élément correspond à une fonction prédicative donnée. Enfin, la méthode findIndex recherche la position du premier élément qui correspond au prédicat.

»Plus d'informations sur le livre sont disponibles sur le site Web de l'éditeur
» Contenu
» Extrait

25% de réduction sur les colporteurs - JavaScript
Lors du paiement de la version papier du livre, un livre électronique est envoyé par e-mail.

Source: https://habr.com/ru/post/fr463465/


All Articles