JavaScript : les Objets
Michel Buffa
Avril 2012
buffa@unice.fr
Nous allons voir comment :
>>>> var myarr = ['red', 'blue', 'yellow', 'purple']; >>> myarr; ["red", "blue", "yellow", "purple"] >>> myarr[0] "red" >>> myarr[3] "purple"
var heros = { race: 'Tortue', metier: 'Ninja' };
Nom de la variable qui contient l'objet = heros,
Au lieu de [ et ] on utilise { et },
Les éléments de l'objet (ses propriétés) sont séparés par une virgule,
Les paires de clés/valeurs sont séparées par : comme dans race:'Tortue'
On peut mettre des simple ou double quotes autour du nom de la propriété, ou rien du tout :
var louis = {age: 40}; var louis = {"age": 40}; var louis = {'age': 40};
Dans certains cas on est obligé de mettre des quotes autour du nom de la propriété :
var objetBizarre = { age: 1, 'oui ou non': 'oui', '!@#$%^&*': true };
Pour des tableaux on parle d'éléments,
Pour des objets on parle de propriétés
Une propriété peut aussi valoir une fonction, dans ce cas on parle de méthode.
var medor = { nom: 'Benji', parle: function(){ alert('Ouah, Ouah!'); } };
Dans certains langages de programmation (Java par ex) on distingue :
JavaScript utilise les tableaux pour le cas 1, et des objets pour le cas 2
var medor = { nom: 'Benji', parle: function(){ alert('Ouah, Ouah!'); } };
Deux syntaxes possibles :
var heros = { race: 'Tortue', metier: 'Ninja' }; >>> heros.race; "Tortue" >>> heros['race']; "Tortue" >>> heros.age; "age is Undefined"
var book = { name: 'Catch-22', published: 1961, author: { firstname: 'Joseph', lastname: 'Heller' } }; >>> book.author.firstname // à préférer "Joseph" >>> book['author']['lastname'] "Heller" >>> book.author['lastname'] // on peut mélanger... "Heller" >>> book['author'].lastname "Heller"
>>> var key = 'firstname'; >>> book.author[key]; "Joseph"
Dans ce cas on est obligé d'utiliser la syntaxe avec [ et ]...
Une méthode étant une propriété on peut utiliser l'opérateur . ou les crochets
var heros = { race: 'Tortue', metier: 'Ninja', parle: function() { return 'Je suis un ' + heros.metier; } } >>> heros.parle(); // recommandée comme syntaxe "Je suis un Ninja" >>>heros['parle'](); // peu utilisé car moins Java-esque "Je suis un Ninja"
Contrairement à Java, il est possible en JavaScript d'ajouter ou de supprimer des propriétés une fois l'objet créé.
>>> var heros = {}; // Objet sans propriétés >>> typeof heros.metier "Undefined" >>> heros.race = 'Tortue'; >>> heros.nom = 'Leonardo'; >>> heros.getNom = function() {return heros.nom;}; >>> hero.getNom(); "Leonardo" >>> delete heros.nom; true >>> hero.getNom(); reference to undefined property heros.nom
Dans l'exemple précédent le code de la méthode getNom() faisait référence au nom de l'objet, il vaut mieux utiliser le ot clé this.
var heros1 = { nom: 'Rafaelo', getNom: function() { return this.nom; } } >>> heros1.getNom(); "Rafaelo"
this correspond à "l'objet courant". Le code est plus portable si on affecte cet objet à une autre variable....
Un exemple suffit à comprendre le principe (remarquez qu'on nomme la fonction comme une classe Java):
function Heros() { this.metier = 'Ninja'; }
On peut maintenant utiliser l'opérateur new :
>>> var monHero = new Heros(); >>>typeof monHero "object" >>> monHero.metier; "Ninja"
function Heros(nom) { this.nom = nom; this.metier = 'Ninja'; this.decrisToi = function() { return "Je suis " + this.nom + ", je suis un " + this.metier; } } >>> var h1 = new Heros('Michelangelo'); >>> var h2 = new Heros('Donatello'); >>> h1.decrisToi(); "Je suis Michelangelo, je suis un Ninja" >>> h2.decrisToi(); "Je suis Donatello, je suis un Ninja"
Note : cela commence un peu à ressembler à des classes Java...non ?
Donner un nom de fonction commençant par une majuscule permet de distinguer les constructeurs !
>>> var monHero = new Heros(); >>>typeof monHero "object"
Mais :
>>> var monHero = Heros(); >>>typeof monHero "undefined"
Normal, car dans ce cas monHero vaut la valeur de retour de Heros() qui ne renvoie rien !
Dans ce cas, le this à l'intérieur de la fonctin Heros() se réfère à ce que l'on appelle l'objet global, qui contient tous les autres.
Il est temps de dire la vérité :
Cas où l'environnement est un navigateur web :
>>> var a = 1; >>> a 1 >>> window.a 1 >>> window['a'] 1 >>> function Heros(nom) {this.nom = nom;} // appel sans new, this = objet global >>> var h = Heros('Leonardo'); >>> typeof h "undefined" >>> typeof h.nom h has no properties h has no properties >>> nom "Leonardo" >>> window.nom "Leonardo"
Si on oublie pas le new :
>>> var h2 = new Heros('Michelangelo'); // On a pas oublié le new ! >>> typeof h2 "object" >>> h2.nom "Michelangelo"
Les fonctions prédéfinies sont des méthodes de l'objet global window :
>>> parseInt('101 dalmatiens') 101 >>> window.parseInt('101 dalmatiens') 101
Quand un objet est créé on lui donne en coulisse une propriété nommée "constructor" :
>>> h2.constructor Heros(nom) >>> typeof a.constructor "function"
Puisque ce constructeur est une fonction, on peut l'appeler :
>>> var h3 = new h2.constructor('Rafaello'); // construit moi comme h2 >>> h3.nom; "Rafaello"
Dans le cas où on construit un objet sous sa forme littérale :
>>> var o = {}; >>> o.constructor; Object() >>> typeof o.constructor; "function"
Object() est le constructeur built-in de JavaScript. Détails viendront plus loin...
instanceof permet de tester avec quel constructeur un objet a été créé
>>> function Heros(){} >>> var h = new Heros(); >>> var o = {}; >>> h instanceof Herso; true >>> h instanceof Object; false // Pas comme en Java ! >>> o instanceof Object; true
En plus de la création littérale et de la création par new, on peut aussi créer des objets à l'aide de fonctions qui en renvoient :
function factory(nom) { return { nom: nom }; } >>> var o = factory('Michel'); >>> o.nom "Michel" >>> o.constructor Object()
Par défaut, toute manipulation d'objet se fait par référence :
>>> var original = {valeur: 1}; >>> var copie = original; >>> copie.valeur 1 >>> copy.valeur = 100; 100 >>> original.valeur 100
Les deux variables copie et original pointent en fait sur le même objets, ce sont deux références au même objet.
Comparer deux objets ne donnera true que s'ils ont la même référence.
Deux objets à priori identiques ne seront pas égaux s'ils n'ont pas la même référence
>>> var fido = {race: 'chien'}; >>> var benji = {race: 'chien'}; >>> benji === fido false >>> benji == fido false >>> var monChien = benji; >>> mydog === benji true >>> mydog === fido false
Objets "wrappers" : Object, Array, Function, Boolean, Number, et String, ils correspondent aux types prédéfinis.
Objets utilitaires : Math, Date, RegExp
Objets pour le debug : Error, etc.
C'est le "père" de tous les objets JavaScript que vous créez. Tous vos objets "héritent" de celui-ci, si on peut parler comme ça...
Ces deux lignes sont équivalentes :
>>> var o = {}; >>> var o = new Object();
On bénéficie de méthodes par défauts comme toString() qui convertit l'objet en Strig:
>>> o.toString() "[object Object]"
>>> alert(o); >>> alert(o.toString()); // équivalent à la ligne précédente >>> "L'objet en String : " + o // toString() implicite ! "L'objet en String : [object Object]"
>>> o.valueOf() === o true
Array() est une fonction built-in que l'on peut utiliser pour construire des tableaux :
>>> var a = new Array(); // équivalent à var a = []; >>> var b = new Array(1,2,3,'quatre'); >>> b; [1, 2, 3, "quatre"]
Piège : si un seul paramètre alors c'est la taille du tableau:
>>> var a2 = new Array(5); >>> a2; [undefined, undefined, undefined, undefined, undefined]
Dans les exemples précédents si on créée des tableaux avec Array() ce sont des objets :
>>> typeof a; "object"
Et on peut bénéficier des méthodes de Object
>>> a.toString(); "1,2,3,quatre" >>> a.valueOf() [1, 2, 3, "quatre"] >>> a.constructor Array()
Les tableaux sont en fait des objets mais spéciaux :
>>> var a = [], o = {}; >>> a.length 0 >>> typeof a.length "number" >>> typeof o.length "undefined"
Hmmm... on peut faire de jolies horreurs quand même :
>>> a[0] = 1; o[0] = 1; >>> a.prop = 2; o.prop = 2; >>> a.length 1
La propriété length ne "compte" que les propriétés numériques !
Si plus grand que la taille du tableau
>>> a.length = 5 // peut agrandir le tableau 5 >>> a [1, undefined, undefined, undefined, undefined]
Si plus petit, réduit le tableau
>>> a.length = 2; 2 >>> a [1, undefined]
Les plus courantes : sort(), join(), slice(), splice(), push() et pop()
>>> var a = [3, 5, 1, 7, 'test']; >>> a.push('new') // ajout en fin et renvoie length 6 >>> a [3, 5, 1, 7, "test", "new"] >>> a.pop() // retire le dernier élément et le renvoie "new" >>> a [3, 5, 1, 7, "test"] >>> var b = a.sort(); >>> b [1, 3, 5, 7, "test"] >>> a [1, 3, 5, 7, "test"] >>> a.join(' et '); "1 et 3 et 5 et 7 et test"
slice() renvoie un sous-tableau sans modifier l'original.
>>> a [1, 3, 5, 7, "test"] >>> b = a.slice(1, 3); // éléments 1 et 2 [3, 5] >>> b = a.slice(0, 1); // élément 0 [1] >>> b = a.slice(0, 2); // éléments 0 et 1 [1, 3] >>> a [1, 3, 5, 7, "test"]
splice() modifie le tableau en enlevant une tranche, éventuellement en ajoutant aussi de nouveaux éléments.
Les deux premiers paramètres sont les indices de début et fin, les autres paramètres sont les éléments à insérer à la place de la tranche enlevée.
>>> a [1, 3, 5, 7, "test"] >>> b = a.splice(1, 2, 100, 101, 102); [3, 5] >>> a [1, 100, 101, 102, 7, "test"] >>> a.splice(1, 3) [100, 101, 102] >>> a [1, 7, "test"]
Les fonctions sont des objets en JavaScript, elles ont toutes un constructeur intitulé Function()
>>> function myfunc(a){return a;} >>> myfunc.constructor Function()
Les fonctions ont aussi une propriété length qui vaut le nombre de paramètres :
>>> function myfunc(a, b, c){return true;} >>> myfunc.length 3
Elles possèdent aussi une propriété caller qui renvoie la fonction appelante :
>>> function A(){return A.caller;} >>> function B(){return A();} >>> B(); B()
Si A est appelée depuis l'espace global, l'appelant vaut null :
>>> A(); null
prototype est la propriété la plus importante des fonctions JavaScript
Elle contient un objet,
Elle n'est utile que lorsqu'on utilise une fonction comme un constructeur, par ex: var heros = new Heros('Michel');
Tous les objets créés par cette fonction/constructeur ont une référence vers la propriété prototype de leur constructeur, et considèrent les propriétés de cet objet prototype comme les leurs.
Voyons quelques exemples...
var unObjet = { nom: 'Ninja', parle: function(){ return 'Je suis : ' + this.nom; } }
Créons une fonction vide, ah, elle a un prototype !
>>> function F(){} >>> typeof F.prototype "object"
Modifions la valeur de cet objet prototype :
>>> F.prototype = unObjet;
Et utilisons F comme un constructeur !
>>> var obj = new F(); >>> obj.nom "Ninja" >>> obj.parle() "Je suis Ninja"
Intéressant non ? Nous y reviendrons...
Function est un descendant de Object, il hérite donc des méthodes de ce dernier, comme toString()
toString() sur une fonction : renvoie le code de la fonction sous forme de String
>>> function myfunc(a, b, c) {return a + b + c;} >>> myfunc.toString() "function myfunc(a, b, c) { return a + b + c; }"
SI on appelle toString sur une fonction native on obtient [native code] :
>>> eval.toString() "function eval() { [native code] }"
Permettent d'emprunter des méthodes à d'autres objets et de les appeler :
var unObjet = { nom: 'Ninja', parlerA: function(interlocuteur){ return 'Hello ' + interlocuteur + ', je suis un ' + this.nom; } } >>> unObjet.parlerA('Michel'); "Hello Michel, je suis un Ninja"
>>> unAutreObjet = {nom: 'Gourou JavaScript'};
UnAutreObjet aime tellement la méthode parlerA() de UnObjet qu'il veut l'appeler :
>>> unObjet.parlerA.call(unAutreObjet, 'Michel'); "Hello Michel, je suis un Gourou JavaScript"
La fonction parlerA() de unObjet a été appelée avec un "this" différent correspondant à unAutreObjet.
On fait cela en appelant la méthode call() d'une méthode pour changer son "this" !
Peut-on faire cela en Java ?
Si la méthode a plus de paramètres, on les ajoute :
unObjet.uneMethode.call(unAutreObjet, 'a', 'b', 'c');
Si on ne passe pas d'objet ou si on passe null comme premier paramètre, c'est l'objet global qui correspondra à "this" dans le corps de la méthode.
apply() est équivalent à call() si ce n'est que les paramètres sont passés dans un tableau :
unObjet.uneMethode.apply(unAutreObjet, ['a', 'b', 'c']); unObjet.uneMethode.call(unAutreObjet, 'a', 'b', 'c');
Les deux lignes précédentes sont équivalentes.
Avec l'exemple précédent :
>>> unObjet.parlerA.apply(unAutreObjet, ['Michel']); "Hello Michel, je suis un Gourou JavaScript"
arguments est comme un tableau (propriété "length") mais ce n'en est pas un, (pas de slice() et sort() par exemple).
arguments.callee : référence la fonction elle-même.
Utile pour faire des fonctions anonymes récursives :
(function(count){ if (count < 5) { alert(count); arguments.callee(++count); } })(1);
L'exemple précédent affiche dans une alerte "1", puis "2", "3" et "4".
Comme en Java, c'est un objet qui wrappe le type prédéfini boolean.
On utilise la méthode valueOf() pour avoir une variable du type prédéfini équivalent.
>>> var b = new Boolean(); >>> typeof b "object" >>> b.valueOf() false >>> typeof b.valueOf() "boolean"
On appelle pour cela Boolean(...) sans new !
>>> Boolean("test") true >>> Boolean("") false >>> Boolean({}) true
N'importe quel objet, même vide, se convertit en "true".
>>> var b1 = new Boolean(true) >>> b1.valueOf() true >>> var b2 = new Boolean(false) >>> b2.valueOf() false
>>> Boolean(b1) true >>> Boolean(b2) true
Wrapper sur le type prédéfini "number".
Number() sans "new" sert à convertir en "number", comme parseInt() ou parseFloat()
>>> var n = Number('12.12'); >>> n 12.12 >>> typeof n "number" >>> var n = new Number('12.12'); >>> typeof n "object"
Comme en JavaScript les fonctions sont des objets, Number() a des propriétés intéressantes :
>>> Number.MAX_VALUE 1.7976931348623157e+308 >>> Number.MIN_VALUE 5e-324 >>> Number.POSITIVE_INFINITY Infinity >>> Number.NEGATIVE_INFINITY -Infinity >>> Number.NaN NaN
Conversions : toFixed(), toExponential(), toString()
>>> var n = new Number(123.456) >>> n.toFixed(1) "123.5" >>> (12345).toExponential() "1.2345e+4" >>> var n = new Number(255); >>> n.toString(); "255" >>> n.toString(10); "255" >>> n.toString(16); "ff" >>> (3).toString(2); "11" >>> (3).toString(10); "3"
new String() construit un objet, on peut utiliser les méthodes et propriétés prédéfinies de String.
>>> var primitive = 'Hello'; >>> typeof primitive; "string" >>> var obj = new String('world'); >>> typeof obj; "object" >>> obj[0] "w" >>> obj[4] "d" >>> obj.length 5
On peut une "string" à partir d'un objet de type String :
>>> obj.valueOf() "world" >>> obj.toString() "world" >>> obj + "" "world"
JavaScript permet d'utiliser certains aspects des String sur des "string" :
>>> "potato".length 6 >>> "tomato"[0] "t" >>> "potato"["potato".length - 1] "o"
On appelle String() sans new, comme pour Boolean().
>>> String(1) "1" >>> String({p: 1}) "[object Object]" >>> String([1,2,3]) "1,2,3"
Ces exemples reviennent à appeler toString() sur les objets en paramètre.
>>> var s = new String("Couch potato"); >>> s.toUpperCase() "COUCH POTATO" >>> s.toLowerCase() "couch potato" >>> s.charAt(0); "C" >>> s[0] "C" >>> s.charAt(101) "" >>> s.indexOf('o') 1 >>> s.indexOf('o', 2); // 2 est l'index de départ ! 7
>>> var s = new String("Couch potato"); >>> s.lastIndexOf('o') 11 >>> s.indexOf('Couch'); // case sensitive 0 >>> s.indexOf('couch'); // si pas trouvé renvoie -1 -1 >>> s.toLowerCase().indexOf('couch') 0
Ile pas tester un index avec un if car si l'index est zéro (début de chaine), alors on teste "false" !
Pas bon :
if (s.indexOf('Couch')) {...}
Bon :
if (s.indexOf('Couch') !== -1) {...}
Permettent d'extraire une sous-chaine, on passe la position de début et la position de fin en paramètre :
>>> var s = new String("Couch potato"); >>> s.slice(1, 5) "ouch" >>> s.substring(1, 5) "ouch"
Différence si le dernier paramètre est négatif :
>>> s.slice(1, -1); // équivalent à s.slice(1, s.length -1) "ouch potat" >>> s.substring(1, -1); // équivalent à s.substring(1,0); "C"
Split renvoie un tableau de chaine, le paramètre est un séparateur, join() construit une String à partir d'un tableau de chaines :
>>> var s = new String("Couch potato"); >>> s.split(" ") ["Couch", "potato"] >>> s.split(' ').join(' '); "Couch potato" >>> s.concat("es"); // équivalent à s = s + "es; "Couch potatoes" >>> s.valueOf(); "Couch potato"
Aucune de ces méthodes ne modifie la chaine de départ.
Ces méthodes utilisent des expressions régulières en arguments, elles seront étudiées un peu plus loin, dans la section concernant l'objet prédéfini RegExp.
Particularité : on ne peut pas faire de "new Math()", mais l'objet Math possède de nombreuses propriétés et fonctions utiles pour les expressions arithmétiques.
>>> Math.PI 3.141592653589793 >>> Math.SQRT2 // racine carrée 1.4142135623730951 >>> Math.E // Constante d'Euler 2.718281828459045 >>> Math.LN2 // Log naturel de 2 0.6931471805599453 Natural logarithm of 10: >>> Math.LN10 // Log naturel de 10 2.302585092994046
Générer un nombre réel aléatoire entre 0 et 1 :
>>> Math.random() 0.3649461670235814
Entre 0 et 100
>>> 100 * Math.random()
Entre min et max : ((max - min) * Math.random()) + min
>>> 8 * Math.random() + 2 // nombre entre 2 et 10 9.175650496668485
Pour arrondir au plus proche, à l'entier supérieur ou inférieur.
Par ex, pour obtenir soit 0 soit 1 :
>>> Math.round(Math.random())
Il y a aussi Math.min() et Math.max(). Exemple pour restreindre une valeur entre 1 et 12 :
>>> Math.min(Math.max(1, input), 12)
>>> Math.pow(2, 8) // 2 puissance 8 256 >>> Math.sqrt(9) // Racine carrée de 9 3
Date() est un constructeur, qui prend plusieurs arguments :
>>> new Date() Tue Jan 08 2008 01:10:42 GMT-0800 (Pacific Standard Time)
Remarque : la valeur retournée est en fait un objet de type Date, ce qui s'affiche est l'appel à toString() sur cet objet.
>>> new Date('2009 11 12') Thu Nov 12 2009 00:00:00 GMT-0800 (Pacific Standard Time) >>> new Date('1 1 2012') Sun Jan 01 2012 00:00:00 GMT-0800 (Pacific Standard Time) >>> new Date('1 mar 2012 5:30') Thu Mar 01 2012 05:30:00 GMT-0800 (Pacific Standard Time)
On peut passer aussi des paramètres numériques pour, dans l'ordre : année, mois (0-11), jour (1-31), heure (0-23), minutes (0-59), secondes (0-59), millisecondes (0-999). On n'est pas obligé de tout passer mais ce sera toujours dans cet ordre.
>>> new Date(2008, 0, 1, 17, 05, 03, 120) Tue Jan 01 2008 17:05:03 GMT-0800 (Pacific Standard Time) >>> new Date(2008, 0, 1, 17) Tue Jan 01 2008 17:00:00 GMT-0800 (Pacific Standard Time) >>> new Date(2008, 1, 28) // 1 c'est Février ! Ca commence à zéro ! Thu Feb 28 2008 00:00:00 GMT-0800 (Pacific Standard Time) >>> new Date(2008, 1, 29) Fri Feb 29 2008 00:00:00 GMT-0800 (Pacific Standard Time) >>> new Date(2008, 1, 30) // Pas de 30 février -> ça donne premier Mars ! Sat Mar 01 2008 00:00:00 GMT-0800 (Pacific Standard Time) >>> new Date(2008, 11, 31) Wed Dec 31 2008 00:00:00 GMT-0800 (Pacific Standard Time) >>> new Date(2008, 11, 32) // 32 Dec -> 1er Janvier ! Thu Jan 01 2009 00:00:00 GMT-0800 (Pacific Standard Time)
On peut construire la date avec un timestamp Unix (nb millisecondes depuis 1970)
>>> new Date(1199865795109) Wed Jan 09 2008 00:03:15 GMT-0800 (Pacific Standard Time)
L'appel de Date() sans "new" renvoie la date courante sous forme de chaine de caractères. Peu importe que l'on passe des paramètres.
>>> Date() "Thu Jan 11 2012 18:15:47 GMT-0800 (Pacific Standard Time)"
// Construction >>> var d = new Date(); >>> d.toString(); "Wed Jan 09 2008 00:26:39 GMT-0800 (Pacific Standard Time)" // Chenger le mois pour Mars >>> d.setMonth(2); 1205051199562 >>> d.toString(); "Sun Mar 09 2008 00:26:39 GMT-0800 (Pacific Standard Time)" // Récupérer le mois >>> d.getMonth(); 2
Date.parse() transforme une chaine de caractère représentant une date en timestamp :
>>> Date.parse('Jan 1, 2008') 1199174400000
Date.UTC() transforme des paramètres numériques représentant une date en timestamp :
>>> Date.UTC(2008, 0, 1) 1199145600000
Quel jour est l'anniversaire de John en 2012 ?
>>> var d = new Date(2012, 5, 20); // Le 20 Juin ! >>> d.getDay(); 3 Dimanche = 0 donc 3 = mercredi, vérifions ! >>> d.toDateString(); "Wed Jun 20 2012" // C'est juste !
Combien de fois l'anniversaire de John sera un dimanche, un lundi, etc... entre 2012 et 3012 :
var joursAnniv = [0,0,0,0,0,0,0]; for (var an = 2012; an < 3012; an++) { joursAnniv[new Date(an, 5, 20).getDay()]++; } >>> joursAnniv; [139, 145, 139, 146, 143, 143, 145] 143 Vendredis et 145 Samedis ! On pourra faire la fête !
JavaScript utilise la syntaxe des expressions régulières (en abrégé : une "regexp") de Perl5.
Une regexp se compose de 1) une pattern et 2) un ou plusieurs modifiers (ou "flags")
Ce cour n'est pas un cours sur les regexp Perl5, il montre comment les utiliser en JavaScript.
Le constructeur RegExp() sert à construire une expression régulière :
// regexp qui matche un élément qui commence par j, finit par t // avec 0 ou plusieurs caractères entre les deux >>> var re = new RegExp("j.*t"); // Autre écriture sans le constructeur >>> var re = /j.*t/;
global : vaut false par défaut. S'arrête au premier match, sinon si true renvoie tous les matches.
ignoreCase : sensible aux majuscules/minuscules. False par défaut. multiline: les matches peuvent être sur plusieurs lignes. False par défaut, lastIndex: la position où démarrer la recherche, valeur par défaut = 0. source: contient la valeur de la regexp.A part lastIndex, ces propriétés ne peuvent être modifiées après la création de la RegExp.
Les trois premieres valeurs du transparent précédent sont des modifiers de la RegExp (global, ignoreCase, multiline).
On peut passer n'importe quelle combinaison de ces paramètres en second paramètre du constructeur :
>>> var re = new RegExp('j.*t', 'gmi'); // l'ordre est peu // important img, gmi, etc. >>> re.global; // vérifions que global est bien positionné true
>>> re.global = false; >>> re.global // On ne peut modifier un modifieur une fois l'objet true // construit !
Voici comment on peut reinitialiser l'objet :
>>> var re = /j.*t/ig; // modifieurs après le slash >>> re.global true
L'objet regexp fournit deux méthodes :
>>> /j.*t/.test("Javascript") false // A cause du J majuscule ! >>> /j.*t/i.test("Javascript") true // Grace au /i ! >>> /j.*t/i.exec("Javascript")[0] "Javascript" // première chaine matchée
>>> var s = new String('HelloJavaScriptWorld'); >>> s.match(/a/); ["a"] >>> s.match(/a/g); ["a", "a"] // g pour search global, deux a dans Java ! >>> s.match(/j.*a/i); ["Java"] >>> s.search(/j.*a/i); 5 // Position du premier match
>>> var s = new String('HelloJavaScriptWorld'); s.replace(/[A-Z]/g, ''); // Supprime toutes les majuscule, globalement "elloavacriptorld" >>> s.replace(/[A-Z]/, ''); // non global ! "elloJavaScriptWorld"
Si lors d'un match on veut inclure le texte matché, on utilise $&.
>>> s.replace(/[A-Z]/g, "_$&"); "_Hello_Java_Script_World"
Lorsque la regexp contient des groupes, notés par des (...), $1 représente le premier groupe, $2 le second, etc...
>>> var email = "stoyan@phpied.com"; >>> var username = email.replace(/(.*)@.*/, "$1"); >>> username; "stoyan"
On peut passer une fonction comme second paramètre d'un appel à replace(). Dans ce cas, la fonction de callback reçoit plusieurs paramètres automatiquement.
>>> function replaceCallback(match){return "_" + match.toLowerCase();} >>> s.replace(/[A-Z]/g, replaceCallback); "_hello_java_script_world"
Paramètres de la fonction de callback (on a utilisé que le premier dans l'exemple précédent):
>>> var glob; // pour mémoriser les paramètres reçus // par le callback >>> var re = /(.*)@(.*)\.(.*)/; // Pour marcher email var callback = function(){ glob = arguments; return arguments[1] + ' at ' + arg arguments[3]; } >>> "stoyan@phpied.com".replace(re, callback); "stoyan at phpied dot com" >>> glob // les paramètres reçus par le callback ["stoyan@phpied.com", "stoyan", "phpied", "com", 0, "stoyan@phpied.com"]
>>> var csv = 'one, two,three ,four'; >>> csv.split(','); ["one", " two", "three ", "four"]
Ah, on a récupéré aussi les espaces ! Utilisons donc une regexp : \s* indique "un ou plusieurs espaces".
>>> csv.split(/\s*,\s*/) // "," mais avec espaces avant et après ! ["one", "two", "three", "four"]
Dans ce cas, c'est comme si la string est un paramètre d'un constructeur de RegExp :
>>> "test".replace('t', 'r') "rest"
Identique à :
>>> "test".replace(new RegExp('t'), 'r') "rest"