Mis à jour le mardi 5 septembre 2017
  • 40 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Ce cours existe en eBook.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Les chaînes de caractères

Connectez-vous ou inscrivez-vous pour bénéficier de toutes les fonctionnalités de ce cours !

Les chaînes de caractères, représentées par l'objet String, ont déjà été manipulées au sein de ce cours, mais il reste bien des choses à voir à leur propos ! Nous allons dans un premier temps découvrir les types primitifs car cela nous sera nécessaire pour vraiment parler des objets comme String, RegExp et autres que nous verrons par la suite.

Les types primitifs

Nous avons vu, tout au long du cours, que les chaînes de caractères étaient des objets String, les tableaux des Array, etc. C'est toujours vrai mais il convient de nuancer ces propos en introduisant le concept de type primitif.

Pour créer une chaîne de caractères, on utilise généralement cette syntaxe :

var myString = "Chaîne de caractères primitive";

Cet exemple crée ce que l'on appelle une chaîne de caractères primitive, qui n'est pas un objet String. Pour instancier un objet String, il faut faire comme ceci :

var myRealString = new String("Chaîne");

Cela est valable pour les autres objets :

var myArray = []; // Tableau primitif
var myRealArray = new Array(); 

var myObject = {}; // Objet primitif
var myRealObject = new Object();

var myBoolean = true; // Booléen primitif
var myRealBoolean = new Boolean("true");

var myNumber = 42; // Nombre primitif
var myRealNumber = new Number("42");

Ce que nous avons utilisé jusqu'à présent était en fait des types primitifs, et non des instances d'objets.

Quelle est la différence entre un type primitif et une instance ?

La différence est minime pour nous, développeurs. Prenons l'exemple de la chaîne de caractères : à chaque fois que nous allons faire une opération sur une chaîne primitive, le JavaScript va automatiquement convertir cette chaîne en une instance temporaire de String, de manière à pouvoir utiliser les propriétés et méthodes fournies par l'objet String. Une fois les opérations terminées, l'instance temporaire est détruite.

Au final, utiliser un type primitif ou une instance revient au même du point de vue de l'utilisation. Mais il subsiste de légères différences avec l'opérateur instanceof qui peut retourner de drôles de résultats…

Pour une raison ou une autre, imaginons que l'on veuille savoir de quelle instance est issu un objet :

var myString = 'Chaîne de caractères';

if (myString instanceof String) {
    // Faire quelque chose
}

La condition sera fausse ! Et c'est bien normal puisque myString est une chaîne primitive et non une instance de String. Pour tester le type primitif, il convient d'utiliser l'opérateur typeof :

if (typeof myString === 'string') {
    // Faire quelque chose
}

typeof permet de vérifier le type primitif (en anglais on parle de datatype). Mais ici aussi faites attention au piège, car la forme primitive d'une instance de String est… object :

alert(typeof myRealString); // Affiche : « object »

Il faudra donc faire bien attention en testant le type ou l'instance d'un objet ! Il est même d'ailleurs déconseillé de faire ce genre de tests vu le nombre de problèmes que cela peut causer. La seule valeur retournée par typeof dont on peut être sûr, c'est "undefined". Nous allons étudier, plus tard dans ce chapitre, une solution pour tester si une variable contient une chaîne de caractères.

L'objet String

L'objet String est l'objet que vous manipulez depuis le début du tutoriel : c'est lui qui gère les chaînes de caractères.

Propriétés

String ne possède qu'une seule propriété, length, qui retourne le nombre de caractères contenus dans une chaîne. Les espaces, les signes de ponctuation, les chiffres… sont considérés comme des caractères. Ainsi, cette chaîne de caractères contient 21 caractères :

alert('Ceci est une chaîne !'.length);

Essayer le code

Mais ! C'est quoi cette manière d'écrire du code ?

En fait, il n'est pas toujours obligatoire de déclarer une variable pour utiliser les propriétés et les méthodes d'un objet. En effet, vous pouvez écrire directement le contenu de votre variable et utiliser une de ses propriétés ou de ses méthodes, comme c'est le cas ici. Notez cependant que cela ne fonctionne pas avec les nombres sous forme primitive car le point est le caractère permettant d'ajouter une ou plusieurs décimales. Ainsi, ce code générera une erreur :

0.toString(); // Une erreur se produira si vous exécutez ce code

Méthodes

String possède quelques méthodes qui sont pour la plupart assez intéressantes mais basiques. Le JavaScript est un langage assez simple, qui ne contient pas énormément de méthodes de base. C'est un peu l'inverse du PHP qui contient une multitude de fonctions pour réaliser un peu tout et n'importe quoi. Par exemple, le PHP possède une fonction pour mettre la première lettre d'une chaîne en majuscule, alors qu'en JavaScript il faudra nous-mêmes récupérer le premier caractère et le mettre en majuscule. Le JavaScript fournit juste quelques méthodes de base, et ce sera à vous de coder vous-mêmes d'autres méthodes ou fonctions selon vos besoins.

La casse et les caractères

toLowerCase() et toUpperCase()

toLowerCase() et toUpperCase() permettent respectivement de convertir une chaîne en minuscules et en majuscules. Elles sont pratiques pour réaliser différents tests ou pour uniformiser une chaîne de caractères. Leur utilisation est simple :

var myString = 'tim berners-lee';

myString = myString.toUpperCase(); // Retourne : « TIM BERNERS-LEE »

Accéder aux caractères

La méthode charAt() permet de récupérer un caractère en fonction de sa position dans la chaîne de caractères. La méthode reçoit en paramètre la position du caractère :

var myString = 'Pauline';

var first = myString.charAt(0); // P
var last = myString.charAt(myString.length - 1); // e

En fait, les chaînes de caractères peuvent être imaginées comme des tableaux, à la différence qu'il n'est pas possible d'accéder aux caractères en utilisant les crochets : à la place, il faut utiliser charAt().

Obtenir le caractère en ASCII

La méthode charCodeAt() fonctionne comme charAt() à la différence que ce n'est pas le caractère qui est retourné mais le code ASCII du caractère.

Créer une chaîne de caractères depuis une chaîne ASCII

fromCharCode() permet de faire plus ou moins l'inverse de charCodeAt() : instancier une nouvelle chaîne de caractères à partir d'une chaîne ASCII, dont chaque code est séparé par une virgule. Son fonctionnement est particulier puisqu'il est nécessaire d'utiliser l'objet String lui-même :

var myString = String.fromCharCode(74, 97, 118, 97, 83, 99, 114, 105, 112, 116); // le mot JavaScript en ASCII

alert(myString); // Affiche : « JavaScript »

Mais quel est l'intérêt d'utiliser les codes ASCII ?

Ce n'est pas très fréquent, mais cela peut être utile dans un cas bien particulier : détecter les touches du clavier. Admettons qu'il faille savoir quelle touche du clavier à été pressée par l'utilisateur. Pour cela, on utilise la propriété keyCode de l'objet Event :

<textarea onkeyup="listenKey(event)"></textarea>

La fonction listenKey() peut être écrite comme suit :

function listenKey(event) {
  
    var key = event.keyCode;

    alert('La touche numéro ' + key + ' a été pressée. Le caractère ' + String.fromCharCode(key) + ' a été inséré.');
}

Essayer le code complet

event.keyCode retourne le code ASCII qui correspond au caractère inséré par la touche. Pour la touche J, le code ASCII est 74 par exemple.

Supprimer les espaces avec trim()

trim() sert à supprimer les espaces avant et après une chaîne de caractères. C'est particulièrement utile quand on récupère des données saisies dans une zone de texte, car l'utilisateur est susceptible d'avoir laissé des espaces avant et après son texte, surtout s'il a fait un copier/coller.

Rechercher, couper et extraire

Connaître la position avec indexOf() et lastIndexOf()

La méthode indexOf() est utile dans deux cas de figure :

  • Savoir si une chaîne de caractères contient un caractère ou un morceau de chaîne ;

  • Savoir à quelle position se trouve le premier caractère de la chaîne recherchée.

indexOf() retourne la position du premier caractère trouvé, et s'il n'y en a pas la valeur -1 est retournée.

var myString = 'Le JavaScript est plutôt cool';
var result = myString.indexOf('JavaScript');

if (result > -1) {
    alert('La chaîne contient le mot "JavaScript" qui débute à la position ' + result);
}

Essayer le code

Ce code a pour but de savoir si la chaîne myString contient la chaîne « JavaScript ». La position de la première occurrence de la chaîne recherchée est stockée dans la variable result. Si result vaut -1, alors la chaîne n'a pas été trouvée. Si, en revanche, result vaut 0 (le premier caractère) ou une autre valeur, la chaîne est trouvée.

Si indexOf() retourne la position de la première occurrence trouvée, lastIndexOf() retourne la position de la dernière.

Notons que ces deux fonctions possèdent chacune un deuxième argument qui permet de spécifier à partir de quel index la recherche doit commencer.

Utiliser le tilde avec indexOf() et lastIndexOf()

Une particularité intéressante et relativement méconnue du JavaScript est son caractère tilde ~. Il s'agit de l'opérateur binaire « NOT » qui a pour rôle d'inverser tous les bits d'une valeur. Comme le binaire ne nous sert pas à grand chose dans le cadre de notre apprentissage, il est plus logique d'expliquer son influence sur les nombres en base décimale : le tilde incrémente la valeur qui le suit et y ajouter une négation, comme ceci :

alert(~2);  // Affiche : « -3 »
alert(~3);  // Affiche : « -4 »
alert(~-2); // Affiche : « 1 »

Hum... Ça ne servirait pas un peu à rien, ce truc ?

Eh bien pas tant que ça ! Le tilde est effectivement très peu utile en temps normal, mais dans le cadre d'une utilisation avec les deux méthodes étudiées, il est redoutablement efficace pour détecter si une chaîne de caractères contient un caractère ou un morceau de chaîne. En temps normal nous ferions comme ceci :

var myString = 'Le JavaScript est plutôt cool';

if (myString.indexOf('JavaScript') != -1) {
    alert('La chaîne contient bien le mot "JavaScript".');
}

Mais au final il est possible d'ajouter un simple petit tilde ~ à la ligne 3 :

var myString = 'Le JavaScript est plutôt cool';

if (~myString.indexOf('JavaScript')) {
    alert('La chaîne contient bien le mot "JavaScript".');
}

En faisant cela, dans le cas où le résultat serait -1, celui-ci va alors se retrouver incrémenté et arriver à 0, ce qui donnera donc une évaluation à false pour notre chaîne de caractères. La valeur -1 étant la seule à pouvoir atteindre la valeur 0 avec le tilde ~, il n'y a pas d'hésitation à avoir vu que tous les autres nombres seront évalués à true !

Oui, cette technique a été conçue pour les parfaits fainéants, mais il y a fort à parier que vous vous en souviendrez. ^^

Extraire une chaîne avec substring(), substr() et slice()

Nous avons vu comment trouver la position d'une chaîne de caractères dans une autre, il est temps de voir comment extraire une portion de chaîne, à partir de cette position.

Considérons cette chaîne :

var myString = 'Thunderseb et Nesk';

Le but du jeu va être de récupérer, dans deux variables différentes, les deux pseudonymes contenus dans myString. Pour ce faire, nous allons utiliser substring(). substring(a, b) permet d'extraire une chaîne à partir de la position a (incluse) jusqu'à la position b (exclue).

Pour extraire « Thunderseb », il suffit de connaître la position du premier espace, puisque la position de départ vaut 0 :

var nick_1 = myString.substring(0, myString.indexOf(' '));

Pour « Nesquik69 », il suffit de connaître la position du dernier espace : c'est à ce moment que commencera la chaîne. Comme «Nesquik69 » termine la chaîne, il n'y a pas besoin de spécifier de deuxième paramètre pour substring(), la méthode va automatiquement aller jusqu'au bout :

var nick_2 = myString.substring(myString.lastIndexOf(' ') + 1); // Ne pas oublier d'ajouter 1, pour commencer au N et non à l'espace

Une autre manière de procéder serait d'utiliser substr(), la méthode sœur de substring(). substr(a, n) accepte deux paramètres : le premier est la position de début, et le deuxième le nombre de caractères à extraire. Cela suppose donc de connaître le nombre de caractères à extraire. Ça limite son utilisation et c'est une méthode que vous ne rencontrerez pas fréquemment, au contraire de substring().

Une dernière méthode d'extraction existe : slice(). slice() ressemble très fortement à substring(), mais avec une option en plus. Une valeur négative est transmise pour la position de fin, slice() va extraire la chaîne jusqu'à la fin, en décomptant le nombre de caractères indiqué. Par exemple, si on ne veut récupérer que « Thunder », on peut faire comme ceci :

var nick_1 = 'Thunderseb'.slice(0, -3);

Couper une chaîne en un tableau avec split()

La méthode split() permet de couper une chaîne de caractères à chaque fois qu'une sous-chaîne est rencontrée. Les « morceaux » résultant de la coupe de la chaîne sont placés dans un tableau.

var myCSV = 'Pauline,Guillaume,Clarisse'; // CSV = Comma-Separated Values

var splitted = myCSV.split(','); // On coupe à chaque fois qu'une virgule est rencontrée

alert(splitted.length); // 3

Essayer le code

Dans cet exemple, splitted contient un tableau contenant trois éléments : « Pauline », « Guillaume » et « Clarisse ».

Tester l'existence d'une chaîne de caractères

Nous l'avons vu plus haut, l'instruction typeof est utile, mais la seule valeur de confiance qu'elle retourne est "undefined". En effet, lorsqu'une variable contient le type primitif d'une chaîne de caractères, typeof retourne bien la valeur "string", mais si la variable contient une instance de String alors on obtient en retour la valeur "object". Ce qui fait que typeof ne fonctionne que dans un cas sur deux, il nous faut donc une autre solution pour gérer le deuxième cas.

Et cette solution existe ! Il s'agit de la méthode valueOf() qui est héritée de Object. Cette méthode renvoie la valeur primitive de n'importe quel objet. Ainsi, si on crée une instance de String :

var string_1 = new String('Test');

et que l'on récupère le résultat de sa méthode valueOf() dans la variable string_2 :

var string_2 = string_1.valueOf();

alors l'instruction typeof montre bien que string_1 est une instance de String et que string_2 est une valeur primitive :

alert(typeof string_1); // Affiche : « object »
alert(typeof string_2); // Affiche : « string »

Essayer le code complet

Grâce à cette méthode, il devient bien plus simple de vérifier si une variable contient une chaîne de caractères. Voici notre code final :

function isString(variable) {
    return typeof variable.valueOf() === 'string'; // Si le type de la valeur primitive est « string » alors on retourne « true »
}

D'accord, cette fonction va s'exécuter correctement si on envoie une instance de String. Mais que va renvoyer valueOf() si on passe une valeur primitive à notre fonction ?

Eh bien, tout simplement la même valeur. Expliquons-nous : valueOf() retourne la valeur primitive d'un objet, mais si cette méthode est utilisée sur une valeur qui est déjà de type primitif, alors elle va retourner la même valeur primitive, ce qui convient très bien vu que dans tous les cas il s'agit de la valeur primitive que nous souhaitons analyser !

Pour vous convaincre, testez donc par vous-mêmes :

alert(isString('Test')); // Affiche : « true »
alert(isString(new String('Test'))); // Affiche : « true »

Essayer le code complet

Notre fonction marche dans les deux cas. :) Alors, est-ce qu'en pratique vous aurez besoin d'une fonction pareille ? La réponse est : assez peu… Mais il est toujours bon de savoir comment s'en servir, non ?

Et enfin, à titre d'information, sachez qu'il est aussi possible d'obtenir une instanciation d'objet à partir d'un type primitif (autrement dit, on fait l'inverse de valueOf()), il suffit de procéder de cette manière :

var myString = Object('Mon texte');

Pour rappel, Object est l'objet dont tous les autres objets (tel que String) héritent. Ainsi, en créant une instance de Object avec un type primitif en paramètre, l'objet instancié sera de même type que la valeur primitive. En clair, si vous passez en paramètre un type primitif string alors vous obtiendrez une instance de l'objet String avec la même valeur passée en paramètre.

En résumé
  • Il existe des objets et des types primitifs. Si leur utilisation semble identique, il faut faire attention lors des tests avec les opérateurs instanceof et typeof. Mais heureusement valueOf() sera d'une aide précieuse.

  • Il est préférable d'utiliser les types primitifs, comme nous le faisons depuis le début de ce cours.

  • String fournit des méthodes pour manipuler les caractères : mettre en majuscule ou en minuscule, récupérer un caractère grâce à sa position et supprimer les espaces de part et d'autre de la chaîne.

  • String fournit aussi des méthodes pour rechercher, couper et extraire.

  • L'utilisation du caractère tilde est méconnue, mais peut se révéler très utile en couple avec indexOf() ou lastIndexOf().

Exemple de certificat de réussite
Exemple de certificat de réussite