Ils fournissent également des méthodes pour appeler en tant que tel. Nous les étudierons bientôt, mais nous
verrons d’abord comment cela fonctionne car, bien entendu, les primitives ne sont pas des objets (et nous
allons le rendre encore plus clair).
Regardons la distinction clé entre les primitives et les objets.
Est une valeur de type primitif. Il y a 6 types primitifs: string, number, boolean, symbol, null et undefined.
Est capable de stocker plusieurs valeurs en tant que propriétés. Peut être créé avec {}, par exemple: {name:
"John", age: 30}. Il existe d'autres types d'objets en JavaScript, par exemple, les fonctions sont des objets.
Une des meilleures choses à propos des objets est que nous pouvons stocker une fonction comme l'une de ses
propriétés:
var john = {
name: "John",
sayHi: function() {
console.log("Hi buddy!");
}
};
john.sayHi();
Nous avons donc créé un objet john avec la méthode sayHi.De nombreux objets intégrés existent déjà, tels que
ceux qui fonctionnent avec des dates, des erreurs, des éléments HTML, etc. Ils ont des propriétés et des
méthodes différentes.
Mais, ces fonctionnalités ont un coût!
Les objets sont «plus lourds» que les primitives. Ils ont besoin de ressources supplémentaires pour soutenir
les mécanismes internes. Mais comme les propriétés et les méthodes sont très utiles en programmation, les
moteurs JavaScript tentent de les optimiser pour réduire la charge supplémentaire.
Par exemple, il existe une méthode str.toUpperCase () qui renvoie une chaîne en majuscule.
Voici comment ça fonctionne:
var str = "Hello";
console.log( str.toUpperCase() ); // HELLO
Nous verrons des méthodes plus spécifiques dans les chapitres Nombres et Chaînes .
Par exemple:
console.log(null.test); // error
Les primitives sauf null et undefined fournissent de nombreuses méthodes utiles. Nous étudierons cela dans
les prochains chapitres.
Formellement, ces méthodes fonctionnent via des objets temporaires, mais les moteurs JavaScript sont bien
ajustés pour optimiser cela en interne, ils ne sont donc pas coûteux à appeler.
Tous les nombres en JavaScript sont stockés au format IEEE-754 au format 64 bits , également appelé «double
précision».Récapitulons et développons ce que nous savons actuellement à leur sujet.
Imaginez que nous ayons besoin d'écrire 1 milliard. La manière évidente est:
var billion = 1000000000;
Mais dans la vie réelle, nous évitons généralement d’écrire une longue chaîne de zéros, car il est facile de les
taper mal. De plus, nous sommes paresseux. Nous écrirons généralement quelque chose comme "1bn"un
milliard ou "7.3bn"7 milliards 300 millions. La même chose est vraie pour la plupart des grands nombres.
En JavaScript, nous raccourcissons un nombre en ajoutant la lettre "e"au nombre et en précisant le nombre de
zéros:
var billion = 1e9;
console.log( billion );
console.log( 7.3e9 );
Maintenant écrivons quelque chose de très petit. Disons, 1 microseconde (un millionième de seconde):
var ms = 0.000001;
Comme avant, utiliser "e"peut aider. Si nous souhaitons éviter d'écrire les zéros explicitement, nous pourrions
dire:
var ms = 1e-6;
Si nous comptons les zéros dans 0.000001, il y en a 6. Alors naturellement c'est 1e-6.En d'autres termes, un
nombre négatif après "e"signifie une division de 1 avec le nombre donné de zéros:
Les nombres hexadécimaux sont largement utilisés en JavaScript pour représenter des couleurs, encoder des
caractères et pour beaucoup d'autres choses. Alors, naturellement, il existe un moyen plus court de les
écrire: 0x puis le nombre.
Par exemple:
console.log( 0xff );
console.log( 0xFF );
Les systèmes de numération binaire et octale sont rarement utilisés, mais également supportés par
les préfixes 0b et 0o:
var a = 0b11111111;
console.log(" a ="+a );
var b = 0o377;
console.log(" b ="+a );
Il n'y a que 3 systèmes de numération avec un tel support. Pour les autres systèmes de numération, nous
devrions utiliser la fonction parseInt() .
La méthode num.toString(base) retourne une représentation sous forme de chaîne num dans le système
numérique avec le donné base.
Par exemple:
var num = 255;
console.log( num.toString(16) ); // ff
console.log( num.toString(2) ); // 11111111
L’arrondissement est l’une des opérations les plus utilisées lors de la manipulation des nombres. Il existe
plusieurs fonctions intégrées pour arrondir:
Math.floor
Math.ceil
Math.round
Supprime tout ce qui suit la virgule sans arrondir: 3.1devient 3, -1.1devient -1.Voici le tableau pour
résumer les différences entre eux:
1. Multiplier et diviser.
Par exemple, pour arrondir le nombre au deuxième chiffre après la décimale, multipliez le nombre par 100,
appelez la fonction d'arrondi puis divisez-la.
var num = 1.23456;
console.log( Math.floor(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
2. La méthode toFixed (n) arrondit le nombre en n chiffres après le point et renvoie une représentation sous
forme de chaîne du résultat.
var num = 12.34;
console.log( num.toFixed(1) ); // "12.3"
Veuillez noter que le résultat de toFixed est une chaîne. Si la partie décimale est plus courte que nécessaire,
des zéros sont ajoutés à la fin:
En interne, un nombre est représenté au format 64 bits IEEE-754 . Il y a donc exactement 64 bits pour stocker
un nombre: 52 d'entre eux sont utilisés pour stocker les chiffres, 11 d'entre eux stockent la position du point
décimal (ils sont zéro pour les nombres entiers), et 1 bit est pour le signe.
Si un nombre est trop grand, le stockage 64 bits serait saturé, donnant potentiellement une infinité:
console.log( 1e500 ); // Infinity
Ce qui est peut-être un peu moins évident, mais qui arrive assez souvent, est la perte de précision. Considérez
ce test :
console.log ( 0.1 + 0.2 == 0.3 ); // false
C'est vrai, si nous vérifions si la somme de 0.1et 0.2 est 0.3, nous obtenons false. Etrange! Qu'est-ce que c'est
alors sinon 0.3?
console.log ( 0.1 + 0.2 ); // 0.30000000000000004
Aie! Il y a plus de conséquences qu'une comparaison incorrecte ici. Imaginez que vous faites un site e-
shopping et les met de visiteurs $0.10 et des $0.20 biens dans leur tableau. Le total de la commande
sera $0.30000000000000004. Cela surprendrait n'importe qui.
Mais pourquoi cela se produit-il?
Un nombre est stocké en mémoire sous sa forme binaire, une séquence de uns et de zéros. Mais les fractions
telles que 0.1, 0.2 qui paraissent simples dans le système numérique décimal, sont en réalité des fractions sans
fin dans leur forme binaire.
En d'autres termes, qu'est-ce que c'est 0.1? C'est un divisé par dix 1/10, un dixième. Dans le système
numérique décimal, ces nombres sont facilement représentables. Comparez - le à un tiers: 1/3. Cela devient
une fraction sans fin 0.33333(3).
Ainsi, la division par pouvoirs 10 est garantie de bien fonctionner dans le système décimal, mais la division
par 3 ne l’est pas. Pour la même raison, dans le système de numération binaire, la division par pouvoirs de 2
est garantie, mais 1/10 devient une fraction binaire sans fin.
Il n’existe aucun moyen de stocker exactement 0,1 ou 0,2 à l’aide du système binaire, tout comme il n’existe
aucun moyen de stocker un tiers sous forme de fraction décimale.
Le format numérique IEEE-754 résout ce problème en arrondissant au nombre le plus proche possible. Ces
règles d’arrondi ne nous permettent normalement pas de voir cette «petite perte de précision», aussi le nombre
apparaît-il 0.3. Mais attention, la perte existe toujours.
Nous pouvons voir cela en action:
console.log( 0.1.toFixed(20) ); // 0.10000000000000000555
Cela souffre du même problème: une perte de précision. Il y a 64 bits pour le numéro, 52 d'entre eux peuvent
être utilisés pour stocker des chiffres, mais cela ne suffit pas. Ainsi, les chiffres les moins significatifs
disparaissent.JavaScript ne déclenche pas d'erreur dans de tels événements. Il fait de son mieux pour adapter
le nombre au format souhaité, mais malheureusement, ce format n’est pas assez grand.
Mais avons-nous besoin de cette fonction? Ne pouvons-nous pas simplement utiliser la comparaison ===
NaN? Désolé, mais la réponse est non. La valeur NaN est unique en ce sens qu'elle ne correspond à rien, y
compris elle-même:
console.log ( NaN === NaN ); // false
isFinite(value) convertit son argument en nombre et renvoie true s'il s'agit d'un nombre régulier,
pas NaN/Infinity/-Infinity:
console.log ( isFinite("15") ); // true
console.log ( isFinite("str") ); // false, because a special value: NaN
console.log ( isFinite(Infinity) ); // false, because a special value: Infinity
Parfois, isFinite() est utilisé pour valider si une valeur de chaîne est un nombre régulier:
var num = +prompt("Enter a number", '');
Console.log( isFinite(num) );
Veuillez noter qu'une chaîne vide ou une chaîne d'espacement seul est traitée comme 0 dans toutes les
fonctions numériques, y compris isFinite().
La conversion numérique utilisant un plus + ou Number() est stricte. Si une valeur n'est pas exactement un
nombre, elle échoue:
Console.log( +"100px" ); // NaN
La seule exception concerne les espaces au début ou à la fin de la chaîne, car ils sont ignorés.
Mais dans la vraie vie, nous avons souvent des valeurs en unités, comme "100px"ou "12pt"en CSS. De plus,
dans de nombreux pays, le symbole monétaire se situe après le montant. Nous avons donc "19€"et
souhaiterions en extraire une valeur numérique.
C'est l’affaire de parseInt() et parseFloat().
Ils «lisent» un nombre d'une chaîne jusqu'à ce qu'ils le puissent. En cas d'erreur, le numéro rassemblé est
renvoyé. La fonction parseInt() retourne un entier, alors que parseFloat() retournera un nombre à virgule
flottante:
console.log( parseInt('100px') );
console.log ( parseFloat('12.5em') );
console.log ( parseInt('12.3') );
console.log ( parseFloat('12.3.4') );
Il y a des situations où parseInt/parseFloatreviendra NaN. Cela arrive quand aucun chiffre ne peut être lu:
console.log ( parseInt('a123') );
JavaScript a un objet Math intégré qui contient une petite bibliothèque de fonctions et de constantes
mathématiques.
Quelques exemples:
Math.random()
En JavaScript, les données textuelles sont stockées sous forme de chaînes. Il n'y a pas de type séparé pour un
seul caractère. Le format interne des chaînes est toujours UTF-16 , il n'est pas lié au codage de page.
Les chaînes peuvent être placées entre guillemets simples, doubles ou croisés:
Les guillemets simples et doubles sont essentiellement les mêmes. Les quotes_croisé, cependant, nous
permettent d’incorporer n’importe quelle expression dans la chaîne, y compris les appels de fonction:
console.log(listePersonne);
Si nous essayons d'utiliser des guillemets simples ou doubles de la même manière, il y aura une erreur:
console.log(listePersonne);
Les guillemets simples et doubles proviennent d'anciens temps de la création linguistique lorsque la nécessité
de chaînes multilignes n'était pas prise en compte. Les quotes_croisé sont apparus beaucoup plus tard et sont
donc plus polyvalents.
Il est encore possible de créer des chaînes multilignes avec des guillemets simples en utilisant un "caractère de
nouvelle ligne", écrit en tant que \n, qui désigne un saut de ligne:
let listePersonne = "Les personnes:\n * Alaoui\n * Slaoui\n * Ibrahimi";
console.log(listePersonne);
console.log( "\u00A9" );
console.log( "\u{20331}" );
console.log( "\u{1F60D}" );
Tous les caractères spéciaux commencent par un caractère barre oblique inverse \. On l'appelle aussi un
"caractère d'échappement». Nous l'utilisons également si nous voulons insérer une citation dans la chaîne.
Comme vous pouvez le constater, nous devons ajouter la citation intérieure par une barre oblique
inversée \'.Bien sûr, cela ne concerne que les guillemets identiques à ceux qui les entourent. Donc, comme
solution plus élégante, nous pourrions utiliser des quotes double et quotes simple:
console.log( "J'habite à sale" ) ;
Notez que la barre oblique inverse \ sert à la lecture correcte de la chaîne par JavaScript, puis disparaît. La
chaîne en mémoire n'a pas \. Vous pouvez le voir clairement dans les exemples ci-dessus.Mais que faire si
nous devons afficher une barre oblique inverse \dans la chaîne?
C'est possible, mais nous devons le doubler comme suit \\:
console.log( `Anti Slache: \\` );
// le premier caractere
console.log( str[0] ); // B
console.log( str.charAt(0) ); // B
// le dernier caractere
console.log( str[str.length - 1] ); // r
Les crochets sont un moyen moderne d’obtenir un élément, bien qu’ils charAt() existent principalement pour
des raisons historiques.
La seule différence entre eux est que si aucun caractère n'est trouvé, [] retourne undefined et charAt() retourne
une chaîne vide:
let str = `Bonjour`;
Les chaînes ne peuvent pas être modifiées en JavaScript. Il est impossible de changer un élément.
Essayons de montrer que ça ne marche pas.
var str = 'Hi';
La première méthode est str.indexOf (substr, pos) .Il recherche le substr dans str, à partir de la position
donnée pos, et renvoie la position où le match a été trouvé ou -1si rien ne peut être trouvé.
Le second paramètre optionnel nous permet de rechercher à partir de la position donnée. Par exemple, la
première occurrence de "id"est à la position 1. Pour rechercher l'occurrence suivante, commençons la
recherche à partir de la position 2:
let str = 'Widget with id';
console.log( str.indexOf('id', 2) ) // 12
Il y a un léger inconvénient indexOf() dans le test avec if. Nous ne pouvons pas le mettre dans le if comme
ceci:
var str = "Widget with id";
if (str.indexOf("Widget")) {
console.log("We found it"); // erreur
}
Le console0.log() dans l'exemple ci-dessus ne marche pas car str.indexOf("Widget") retourne 0 (ce qui
signifie qu'il a trouvé la correspondance à la position de départ). Oui, mais if considère 0 comme false.
Nous devrions donc vérifier -1, comme ceci:
var str = "Widget with id";
if (str.indexOf("Widget") != -1) {
console.log("We found it"); // ça marche
}
Les plus modernes méthode str.includes (substr, pos) qui retourne true/false selon que str contient la
chaine substr à l’intérieur. C’est le bon choix si nous devons tester le match, mais nous n'avons pas besoin de
sa position:
Des valeurs négatives pour start/end sont également possibles. Ils veulent dire que la position est comptée à
partir de la fin de la chaîne:
var str = "Bonjour";
console.log( str.slice(-4, -1) ); //jou
str.substring(start [, end]). Renvoie la partie de la chaîne entre start et end.C'est presque la même chose
que slice(), mais ça permet start d'être plus grand que end.
console.log( str.substring(2, 6) );
console.log( str.substring(6, 2) );
console.log( str.slice(2, 6) );
console.log( str.slice(6, 2) );
Les arguments négatifs ne sont pas supportés (contrairement à slice()), ils sont traités comme 0.
str.substr(start [, length]). Retourne la partie de la chaîne de start, avec le donné length.
Contrairement aux méthodes précédentes, celle-ci nous permet de spécifier la longueur de la chaine finale au
lieu de la position:
var str = "stringify";
console.log( str.substr(2, 4) );
Le premier argument peut être négatif, compter à partir de la fin:
var str = "stringify";
console.log( str.substr(-4, 2) );
Comme nous l'avons vu dans le chapitre des opérateurs conditionnels. Les chaînes sont comparées caractère
par caractère dans l'ordre alphabétique.
1. Une lettre minuscule est toujours supérieure à la majuscule:
//''<0..9<[A-Z]<[a-z]
console.log( ''<'0' ); // true
console.log( '0'<'A' ); // true
console.log( 'A'<'a' ); // true
Il existe 3 types de citations. Les quotes croisés permettent à une chaîne de s'étendre sur plusieurs lignes et
d'intégrer des expressions.
Les chaînes en JavaScript sont codées en UTF-16.
Nous pouvons utiliser des caractères spéciaux tels que \n et insérer des lettres en utilisant leur unicode \uxxxx.
Pour obtenir un caractère, utilisez: [].
Pour obtenir une sous-chaîne, utilisez: slice() , subString() ou subStr()
Pour en minuscules / majuscules une chaîne, utilisez: toLowerCase()/toUpperCase().
Pour rechercher une sous-chaîne, utilisez:, indexOf() ou includes()/startsWith()/endsWith() pour de simples
vérifications.
Il existe plusieurs autres méthodes utiles dans les chaînes:
str.trim() - supprime les espaces du début et de la fin de la chaîne.
str.repeat(n) - répète les n fois la chaîne dans str.
…et plus. Voir le manuel pour plus de détails.
Les chaînes ont aussi des méthodes pour rechercher / remplacer avec des expressions régulières. Mais ce
sujet mérite un chapitre séparé, nous y reviendrons plus tard.
Les objets vous permettent de stocker des collections de valeurs à clé. C'est très bien. Mais assez souvent, nous
trouvons qu'il nous faut une collection ordonnée , où nous avons un 1er, un 2ème, un 3ème élément, etc. Par
exemple, nous avons besoin de cela pour stocker une liste de quelque chose: utilisateurs, biens, éléments
HTML, etc.
Il n'est pas pratique d'utiliser un objet, car il ne fournit aucune méthode pour gérer l'ordre des éléments. Nous
ne pouvons pas insérer une nouvelle propriété "entre" celles existantes. Les objets ne sont tout simplement pas
destinés à un tel usage.
Il existe une structure de données spéciale nommée Array pour stocker les collections ordonnées.
Il existe deux syntaxes pour créer un tableau vide:
var arr = new Array();
var arr = [];
Presque tout le temps, la deuxième syntaxe est utilisée. Nous pouvons fournir les éléments initiaux entre
parenthèses:
var fruits = [
"Apple",
"Orange",
"Plum",
];
Le style «virgule finale» facilite l'insertion / la suppression d'éléments, car toutes les lignes se ressemblent.
Une file d'attente est l'une des utilisations les plus courantes d'un tableau. En informatique, cela signifie une
collection ordonnée d’éléments qui supporte deux opérations:
push ajoute un élément à la fin.
shift obtenir un élément depuis le début, en faisant avancer la file d'attente, de sorte que le deuxième élément
devienne le premier.
Les tableaux prennent en charge les deux opérations. En pratique, nous le rencontrons très souvent. Par
exemple, une file d'attente de messages devant être affichés à l'écran. Il existe un autre cas d'utilisation pour
les tableaux: la structure de données nommée stack .
Il supporte deux opérations:
push ajoute un élément à la fin.
pop prend un élément de la fin.
Ainsi, de nouveaux éléments sont ajoutés ou pris toujours à la "fin".
Une pile est généralement illustrée par un jeu de cartes: de nouvelles cartes sont ajoutées en haut ou prises en
haut:
Pour les piles, le dernier élément envoyé est reçu en premier, c'est le principe LIFO (dernier entré, premier
sorti). Pour les files d'attente, nous avons FIFO (First-In-First-Out).
Les tableaux en JavaScript peuvent fonctionner à la fois en file d'attente et en pile. Ils vous permettent
d'ajouter / supprimer des éléments à la fois du début ou de la fin.
En informatique, la structure de données qui le permet s'appelle deque .
Méthodes qui fonctionnent avec la fin du tableau:
Pop()
Push()
Shift()
Extrait le premier élément du tableau et le renvoie:
var fruits = ["Apple", "Orange", "Pear"];
console.log( fruits );
console.log( fruits.shift() );
console.log( fruits );
Unshift()
Ajoutez l'élément au début du tableau:
var fruits = ["Orange", "Pear"];
console.log( fruits );
fruits.unshift('Apple');
console.log( fruits );
… Mais ce qui rend les tableaux vraiment spéciaux, c'est leur représentation interne. Le moteur tente de
stocker ses éléments dans la zone de mémoire contiguë, l'un après l'autre, comme indiqué sur les illustrations
de ce chapitre. Il existe également d'autres optimisations permettant de faire fonctionner les tableaux très
rapidement.
Mais ils se cassent tous si nous cessons de travailler avec un tableau comme avec une «collection ordonnée»
et commençons à le travailler comme s'il s'agissait d'un objet normal.
Par exemple, techniquement, nous pouvons le faire:
var fruits = [];
console.log( fruits );
fruits[99999] = 5;
console.log( fruits );
fruits.age = 25;
console.log( fruits );
C'est possible, car les tableaux sont des objets à leur base. Nous pouvons leur ajouter des propriétés.
Mais le moteur verra que nous travaillons avec le tableau comme avec un objet normal. Les optimisations
spécifiques aux tableaux ne sont pas adaptées à ce type de situation et seront désactivées. Leurs avantages
disparaissent.
Les moyens d'abuser d'un tableau:
Ajouter une propriété non numérique comme arr.test = 5.
Faites des trous, comme: ajoutez arr[0] puis arr[1000] (et rien entre eux).
Remplissez le tableau dans l'ordre inverse, comme arr[1000], arr[999] etc.
Veuillez considérer les tableaux comme des structures spéciales pour travailler avec les données
ordonnées . Ils fournissent des méthodes spéciales pour cela. Les tableaux sont soigneusement réglés dans les
moteurs JavaScript pour fonctionner avec des données ordonnées contiguës, veuillez les utiliser de cette
manière. Et si vous avez besoin de clés arbitraires, il y a de fortes chances que vous ayez besoin d'un objet
régulier {}.
Pourquoi est-il plus rapide de travailler avec la fin d'un tableau qu'avec son début? Voyons ce qui se passe
pendant l'exécution:
fruits.shift();
Il ne suffit pas de prendre et de supprimer l'élément avec le numéro 0. D'autres éléments doivent également
être renumérotés.
L’opération shift() doit faire 3 choses:
1. Supprimez l'élément avec l'index 0.
2. Déplacez tous les éléments à gauche, renumérotez-les de l'index 1à 0, de 2à 1 et ainsi de suite.
3. Mettre à jour la propriété length.
Plus il y a d'éléments dans le tableau, plus il y a de temps pour les déplacer, plus il y a d'opérations en
mémoire.
La même chose se produit avec unshift(): pour ajouter un élément au début du tableau, nous devons d’abord
déplacer les éléments existants vers la droite, en augmentant leur index.
Et avec push()/pop()? Ils n'ont pas besoin de déplacer quoi que ce soit. Pour extraire un élément de la fin, la
méthode pop() nettoie l'index et le raccourcit length.
Les actions pour l'opération pop():
fruits.pop();
La méthode pop() n'a pas besoin de déplacer quoi que ce soit, car les autres éléments conservent leurs
index. C'est pourquoi c'est extrêmement rapide.
L'une des méthodes les plus anciennes de cycle des éléments de tableau est la boucle for sur les index:
var arr = ["Apple", "Orange", "Pear"];
console.log(arr);
for (var i = 0; i < arr.length; i++) {
console.log( arr[i] );
}
Mais pour les tableaux, il existe une autre forme de boucle for..of:
var fruits = ["Apple", "Orange", "Plum"];
console.log(arr);
for (var fruit of fruits) {
console.log( fruit );
}
Le for..of ne donne pas accès au numéro de l'élément actuel, mais à sa valeur, mais dans la plupart des cas,
cela suffit. Et c'est plus court.
Techniquement, les tableaux étant des objets, il est également possible d'utiliser for..in:
var arr = ["Apple", "Orange", "Pear"];
console.log(arr);
for (var key in arr) {
console.log( arr[key] );
}
Mais c'est en fait une mauvaise idée. Il y a des problèmes potentiels avec cela:
1. La boucle for..in parcourt toutes les propriétés , pas seulement les propriétés numériques.
Dans le navigateur et dans d'autres environnements, il existe des objets dits «de type tableau» qui ressemblent
à des tableaux . Autrement dit, ils ont des propriétés length et des propriétés d'index, mais ils peuvent
également avoir d'autres propriétés et méthodes non numériques, dont nous n'avons généralement pas
besoin. La boucle for..in les listera cependant. Donc, si nous devons travailler avec des objets de type
tableau, ces propriétés «supplémentaires» peuvent devenir un problème.
2. La boucle for..in est optimisée pour les objets génériques, pas les tableaux, et est donc 10 à 100 fois plus
lente. Bien sûr, c'est encore très rapide.
Généralement, nous ne devrions pas utiliser for..in pour les tableaux.
La propriété length est automatiquement mise à jour lorsque nous modifions le tableau. Pour être précis, il ne
s'agit pas du nombre de valeurs du tableau, mais du plus grand index numérique plus un.
Par exemple, un seul élément avec un grand index donne une grande longueur:
var fruits = [];
fruits[25] = "Apple";
console.log( fruits );
console.log( fruits.length ); // 126
Notez que nous n'utilisons généralement pas de tableaux de ce type. Une autre chose intéressante à propos de
la propriété length est qu'il est accessible en écriture.
Si nous l'augmentons manuellement, rien d'intéressant ne se produit. Mais si nous le diminuons, le tableau est
tronqué. Le processus est irréversible, voici l'exemple:
let arr = [1, 2, 3, 4, 5];
console.log( arr );
arr.length = 2;
console.log( arr );
arr.length = 5;
console.log( arr[3] );
console.log( arr );
Ainsi, la façon la plus simple pour effacer le tableau est le suivant : arr.length = 0;
Les tableaux peuvent avoir des éléments qui sont aussi des tableaux. On peut l'utiliser pour des tableaux
multidimensionnels, pour stocker des matrices:
var matrice = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log( matrice );
console.log( matrice[1][1] );
Les tableaux ont leur propre implémentation de la méthode String() qui renvoie une liste d'éléments séparés
par des virgules.
Par exemple:
var arr = [1, 2, 3];
La déclaration:
var arr = [item1, item2...];
var arr = new Array(item1, item2...);
L'appel à new Array(number) crée un tableau de longueur donnée, mais sans éléments.
La propriété length est la longueur du tableau ou, plus précisément, son dernier index numérique plus un. Il
est auto-ajusté par les méthodes de tableau.
Si nous raccourcissons manuellement length, le tableau est tronqué.
Nous pouvons utiliser un tableau comme un deque avec les opérations suivantes:
push(...items)ajoute itemsà la fin.
pop() supprime l'élément de la fin et le renvoie.
shift() supprime l'élément du début et le retourne.
unshift(...items) ajoute des éléments au début.
Pour boucler sur les éléments du tableau:
for (let i=0; i<arr.length; i++) - fonctionne le plus rapidement, compatible ancien navigateur.
for (let item of arr) - la syntaxe moderne pour les éléments uniquement,
for (let i in arr) - ne jamais utiliser.
Nous reviendrons sur les tableaux et étudierons davantage de méthodes pour ajouter, supprimer, extraire des
éléments et trier des tableaux dans le chapitre Méthodes de tableaux.
Les tableaux fournissent beaucoup de méthodes. Pour faciliter les choses, dans ce chapitre, ils sont divisés en
groupes.
L'élément a été supprimé, mais le tableau a toujours 3 éléments, nous pouvons le voir arr.length == 3.
C'est naturel, car delete obj.key supprime une valeur par le key. C'est tout ce que ça fait. Parfait pour les
objets. Mais pour les tableaux, nous voulons généralement que le reste des éléments se déplace et occupe la
place libérée. Nous nous attendons à avoir un tableau plus court maintenant.
Donc, des méthodes spéciales doivent être utilisées.
La méthode arr.splice (str) est un couteau suisse pour les tableaux. Il peut tout faire: ajouter, supprimer et
insérer des éléments.
Dans l'exemple suivant, nous supprimons 3 éléments et les remplaçons par les deux autres:
var arr = ["I", "study", "JavaScript", "right", "now"];
console.log( arr ) ;
arr.splice(0, 3, "Let's", "dance");
console.table( arr ) ;
Nous pouvons voir ici que splice() renvoie le tableau des éléments supprimés:
var arr = ["I", "study", "JavaScript", "right", "now"];
console.log( arr );
var eleSup = arr.splice(0, 2);
console.log( eleSup );
La méthode splice() est également capable d'insérer les éléments sans aucune suppression. Pour cela, nous
devons mettre deleteCount à 0:
var arr = ["I", "study", "JavaScript"];
console.log( arr );
arr.splice(2, 0, "complex", "language");
console.log( arr );
Ici et dans d'autres méthodes de tableau, les index négatifs sont autorisés. Ils spécifient la position à partir de
la fin du tableau, comme ici:
Elle retourne un nouveau tableau où il copie tous les éléments index commencent "start"à "end"(non
compris "end"). Les deux start et end peuvent être négatifs, dans ce cas, la position à partir de la fin du
tableau est supposée.
Cela fonctionne comme str.slice(), mais crée des sous-tableaux au lieu de sous-chaînes.
Par exemple:
var str = "test";
var arr = ["t", "e", "s", "t"];
console.log( str.slice(1, 3) );
console.log( arr.slice(1, 3) );
console.log( str.slice(-2) );
console.log( arr.slice(-2) );
arr.concat(arg1, arg2...) ;
Il accepte n'importe quel nombre d'arguments - des tableaux ou des valeurs. Le résultat est un nouveau tableau
contenant les éléments de arr, puis arg1, arg2 etc
.Si un argument est un tableau ou une propriété Symbol.isConcatSpreadable, tous ses éléments sont
copiés. Sinon, l'argument lui-même est copié.
Par exemple:
var arr = [1, 2];
console.log(arr);
arr=arr.concat([3, 4])
console.log(arr);
arr=arr.concat([3, 4], [5, 6]);
console.log(arr);
Normalement, il ne copie que les éléments des tableaux (les «étale»). Autres objets, même s'ils ressemblent à
des tableaux, ajoutés dans leur ensemble:
var arr = [1, 2];
var arrayObj = {
0: "something",
length: 1
};
console.log( arr.concat(arrayObj) );
… Mais si un objet de type tableau a une propriété Symbol.isConcatSpreadable, ses éléments sont ajoutés à la
place:
var arr = [1, 2];
var arrayObj = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2
};
console.log( arr.concat(arrayObj) );
Ce sont des méthodes pour rechercher quelque chose dans un tableau.
console.log( arr.indexOf(0) );
console.log( arr.indexOf(false) );
console.log( arr.indexOf(null) );
console.log( arr.includes(1) );
Notez que les méthodes utilisent la comparaison ===. Donc, si nous cherchons false, il trouve
exactement false et non le zéro.Si nous voulons vérifier l'inclusion et ne voulons pas connaître l'index exact,
nous préférons arr.includes().
En outre, une différence très mineure includes est qu'il gère correctement NaN, contrairement
à indexOf()/lastIndexOf():
const arr = [NaN];
console.log( arr.indexOf(NaN) );
console.log( arr.includes(NaN) );
});
console.log(user.name); // John
Dans la vie réelle, les tableaux d'objets sont une chose courante, donc la méthode find() est très utile.Notez
que dans l'exemple, nous fournissons find() une fonction à un seul argument item => item.id == 1. D'autres
paramètres de find() sont rarement utilisés.
La méthode arr.findIndex() est essentiellement la même, mais elle retourne l'index où l'élément a été trouvé à
la place de l'élément lui-même.
filter
La méthode find() recherche un seul (premier) élément qui renvoie la fonction true.
S'il peut y en avoir beaucoup, nous pouvons utiliser arr.filter (fn) .
La syntaxe est à peu près la même que find(), mais elle renvoie un tableau d'éléments correspondants:
let results = arr.filter(function(item, index, array) {
});
Par exemple:
var users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
console.log(someUsers.length); // 2
map()
La méthode arr.map est l’une des plus utiles et des plus utilisées.
La syntaxe est la suivante:
var result = arr.map(function(item, index, array) {
})
Il appelle la fonction pour chaque élément du tableau et renvoie le tableau de résultats. Par exemple, ici nous
transformons chaque élément dans sa longueur:
var lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length)
console.log(lengths);
sort(fn)
La méthode arr.sort() trie le tableau en place .
Par exemple:
var arr = [ 1, 2, 15 ];
console.log("Avant le tri :"+ arr );
arr=arr.sort();
console.log("Apres le tri :"+ arr );
Par exemple:
function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
L'algorithme peut comparer un élément plusieurs fois dans le processus, mais il essaie de faire le moins de
comparaisons possible.
var arr = [ 1, 2, 15 ];
arr.sort(function(a, b) { return a - b; });
console.log(arr); // 1, 2, 15
reverse()
La méthode arr.reverse() inverse l'ordre des éléments dans arr.
Par exemple:
var arr = [1, 2, 3, 4, 5];
console.log( arr );
arr.reverse();
console.log( arr );
Voici la situation de la vraie vie. Nous écrivons une application de messagerie, et la personne qui entre dans la
liste délimitée par des virgules de récepteurs: John, Pete, Mary. Mais pour nous, un tableau de noms serait
beaucoup plus confortable qu'une simple chaîne. Comment l'obtenir?
La méthode str.split (delim) fait exactement cela. Il divise la chaîne en un tableau par le délimiteur
donné delim.
Dans l'exemple ci-dessous, nous nous séparons par une virgule suivie d'un espace:
var names = 'Bilbo, Gandalf, Nazgul';
La méthode split() a un deuxième argument numérique facultatif - une limite sur la longueur du tableau. S'il
est fourni, les éléments supplémentaires sont ignorés. En pratique, il est rarement utilisé cependant:
var arr = 'Bilbo, Gandalf, Nazgul, Saruman'.split(', ', 2);
console.log(arr);
Split() en lettres
reduce()/reduceRight()
Lorsque nous devons parcourir un tableau, nous pouvons utiliser forEach.Lorsque nous devons itérer et
renvoyer les données pour chaque élément, nous pouvons utiliser map.
Les méthodes arr.reduce() et arr.reduceRight() appartiennent également à cette race, mais sont un peu plus
complexes. Ils sont utilisés pour calculer une valeur unique basée sur le tableau.
La syntaxe est la suivante:
var value = arr.reduce(function(previousValue, item, index, arr) {
// ...
}, initial);
La fonction est appliquée aux éléments. Vous remarquerez peut-être les arguments familiers, à partir du 2e:
item - est l'élément actuel du tableau.
index - est sa position.
arr - est le tableau.
Jusqu'ici, comme forEach/map. Mais il y a un autre argument:
previousValue- est le résultat de l'appel de fonction précédent, initial pour le premier appel.
Le moyen le plus simple à comprendre est l'exemple.Ici nous obtenons une somme de tableau sur une ligne:
var arr = [1, 2, 3, 4, 5];
var result = arr.reduce((sum, current) => sum + current, 0);
console.log(result);
Ici, nous avons utilisé la variante la plus commune reduce() qui utilise seulement 2 arguments.
Voyons les détails de ce qui se passe.
1. Lors de la première exécution, sum la valeur initiale (le dernier argument de reduce) est égale à 0et current le
premier élément du tableau est égal à 1. Donc, le résultat est 1.
2. Lors de la deuxième exécution, sum = 1nous y ajoutons le deuxième élément de tableau ( 2) et renvoyons-le.
3. À la 3ème manche, sum = 3nous y ajoutons encore un élément, et ainsi de suite…
Le flux de calcul:
Ou sous la forme d'une table, où chaque ligne représente un appel de fonction sur l'élément de tableau suivant:
Comme on peut le constater, le résultat de l'appel précédent devient le premier argument du suivant.Nous
pouvons également omettre la valeur initiale:
var arr = [1, 2, 3, 4, 5];
var result = arr.reduce((sum, current) => sum + current);
console.log( result );
Le résultat est le même. En effet, s'il n'y a pas d'initiale, reduceprend le premier élément du tableau comme
valeur initiale et lance l'itération à partir du deuxième élément.
Le tableau de calcul est le même que ci-dessus, moins la première ligne.Mais une telle utilisation nécessite un
soin extrême. Si le tableau est vide, alors reduceappeler sans valeur initiale génère une erreur.
Voici un exemple
var arr = [];
// Error: Reduce of empty array with no initial value
// if the initial value existed, reduce would return it for the empty arr.
arr.reduce((sum, current) => sum + current);
Il est donc conseillé de toujours spécifier la valeur initiale.La méthode arr.reduceRight fait la même chose,
mais va de droite à gauche.
Iteration: forEach()
La méthode arr.forEach() permet d'exécuter une fonction pour chaque élément du tableau.
La syntaxe :
arr.forEach(function(item, index, array) {
});
Et ce code est plus élaboré sur leurs positions dans le tableau cible:
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
console.log(`${item} is at index ${index} in ${array}`);
});
Array.isArray
Les tableaux ne forment pas un type de langue distinct. Ils sont basés sur des objets.Cela typeof ne vous
aide donc pas à distinguer un objet simple d'un tableau:
console.log(typeof {});
console.log(typeof []);
Mais les tableaux sont utilisés si souvent qu'il existe une méthode spéciale pour cela: Array.isArray
(valeur) . Il retourne true si le value est un tableau, et false sinon.
console.log(Array.isArray({}));
console.log(Array.isArray([]));
La plupart des méthodes supportent “thisArg”
Presque toutes les méthodes de tableau qui appellent des fonctions - comme find(), filter(), map(), à
l'exception notable de sort(), acceptent un paramètre supplémentaire en option thisArg.
Ce paramètre n'est pas expliqué dans les sections ci-dessus, car il est rarement utilisé. Mais pour être complet,
nous devons le couvrir.
Voici la syntaxe complète de ces méthodes:
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
La valeur du paramètre thisArg devient this pour func.Par exemple, nous utilisons ici une méthode d'objet en
tant que filtre et thisArg est très pratique:
var user = {
age: 18,
younger(otherUser) {
return otherUser.age < this.age;
}
};
var users = [
{age: 12},
{age: 16},
{age: 32}
];
var youngerUsers = users.filter(user.younger, user);
console.log(youngerUsers.length); // 2
Dans l'appel ci-dessus, nous utilisons user.younger comme filtre et fournissons également le contexte
user. Si nous ne fournissions pas le contexte, users.filter(user.younger) nous appellerions user.younger une
fonction autonome avec this=undefined. Cela signifierait une erreur instantanée.