Mis à part la lisibilité, existe-t-il des différences perceptibles (performances) entre l’utilisation de
str.indexOf("src")
et
str.match(/src/)
Personnellement, je préfère match
(et regexp) mais les collègues semblent aller dans le sens inverse. Nous nous demandions si cela importait ...?
MODIFIER:
J'aurais dû dire dès le départ qu'il s'agit de fonctions qui effectueront une correspondance partielle avec une chaîne simple (pour récupérer des identifiants dans les attributs de classe pour JQuery) plutôt que des recherches complètes d'expressions rationnelles avec des caractères génériques, etc.
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
C'est donc la différence entre:
string.indexOf('DisablesGuiClass-');
CONTRE
string.match(/DisablesGuiClass-/)
RegExp est en effet plus lent que indexOf (vous pouvez le voir ici ), bien que normalement cela ne devrait pas être un problème. Avec RegExp, vous devez également vous assurer que la chaîne est correctement échappée, ce qui est une chose supplémentaire à considérer.
Mis à part ces deux problèmes, si deux outils font exactement ce dont vous avez besoin, pourquoi ne pas choisir le plus simple?
Votre comparaison peut ne pas être tout à fait juste. indexOf
est utilisé avec des chaînes simples et est donc très rapide; match
prend une expression régulière - bien sûr, cela peut être plus lent en comparaison, mais si vous voulez faire un match de regex, vous n'irez pas loin avec indexOf
. D'autre part, les moteurs d'expression régulière peuvent être optimisés et leurs performances se sont améliorées au cours des dernières années.
Dans votre cas, où vous cherchez une chaîne textuelle, indexOf
devrait suffire. Cependant, il existe toujours une application pour les expressions rationnelles: si vous devez faire correspondre les mots entier et si vous souhaitez éviter de faire correspondre les sous-chaînes, les expressions rationnelles vous donnent des "ancres de limite de mot". Par exemple:
indexOf('bar')
va trouver bar
trois fois dans bar, fubar, barmy
, alors que
match(/\bbar\b/)
ne correspondra à bar
que s'il ne fait pas partie d'un mot plus long.
Comme vous pouvez le constater dans les commentaires, certaines comparaisons ont montré qu'une regex peut être plus rapide que indexOf
; si elle est critique en termes de performances, vous devrez peut-être profiler votre code.
Si vous essayez de rechercher des occurrences de sous-chaîne sans tenir compte de la casse, alors match
semble être plus rapide qu'une combinaison de indexOf
et toLowerCase()
Vérifiez ici - http://jsperf.com/regexp-vs-indexof/152
Vous demandez si str.indexOf('target')
ou str.match(/target/)
devrait être préféré. Comme d'autres affiches l'ont suggéré, les cas d'utilisation et les types de retour de ces méthodes sont différents. La première demande "où dans str
puis-je d'abord trouver 'target'
?" La seconde demande "str
correspond-il à l'expression rationnelle et, dans l'affirmative, quels sont tous les éléments correspondants pour les groupes de capture associés?"
Le problème est qu’aucun d’entre eux n’est techniquement conçu pour poser la question plus simple: "la chaîne contient-elle la sous-chaîne?" Il y a quelque chose qui est explicitement conçu pour le faire:
var doesStringContainTarget = /target/.test(str);
Utiliser regex.test(string)
présente plusieurs avantages:
str.match(/target/)
(et ses rivaux str.indexOf('target')
)str
est undefined
ou null
, vous obtiendrez false
(le résultat souhaité) au lieu de lancer une TypeError
L'utilisation de indexOf
devrait, en théorie, être plus rapide qu'un regex lorsque vous cherchez simplement du texte brut, mais vous devez effectuer vous-même des tests comparatifs si vous vous souciez de la performance.
Si vous préférez match
et qu'il est assez rapide pour vos besoins, allez-y.
Pour ce qui en vaut la peine, je suis d’accord avec vos collègues sur ce point: j’utiliserais indexOf
lorsque je chercherais une chaîne simple et je n’utiliserais match
etc. que lorsque j’ai besoin des fonctionnalités supplémentaires fournies par les expressions régulières.
La performance indexOf
sera à tout le moins légèrement plus rapide que match
. Tout se résume à la mise en œuvre spécifique. Pour décider lequel utiliser, posez-vous la question suivante:
Est-ce qu'un indice entier suffira ou est-ce que je besoin de la fonctionnalité d'un RegExp résultat du match?
Outre les conséquences sur les performances, qui sont traitées dans d'autres réponses, il est important de noter que les valeurs de retour pour chaque méthode sont différentes. les méthodes ne peuvent donc pas simplement être substituées sans changer également votre logique.
Valeur renvoyée de .indexOf
: integer
Index de l'objet
String
appelant de la première occurrence de la valeur spécifiée, démarrant la recherche àfromIndex
.
Retourne-1
si la valeur est introuvable.
Valeur renvoyée de .match
: array
Un tableau contenant l'intégralité du résultat de la correspondance et les résultats correspondants capturés entre parenthèses.
Retournenull
s'il n'y a pas de correspondance.
Étant donné que .indexOf
renvoie 0
si la chaîne d'appel commence avec la valeur spécifiée, un test de vérité simple échouera.
Par exemple:
Étant donné cette classe…
class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder'
… Les valeurs de retour pour chacune seraient différentes:
// returns `0`, evaluates to `false`
if (string.indexOf('DisablesGuiClass-')) {
… // this block is skipped.
}
contre.
// returns `["DisablesGuiClass-"]`, evaluates to `true`
if (string.match(/DisablesGuiClass-/)) {
… // this block is run.
}
La méthode correcte pour exécuter un test de vérité avec le retour de .indexOf
consiste à tester contre -1
:
if (string.indexOf('DisablesGuiClass-') !== -1) {
// ^returns `0` ^evaluates to `true`
… // this block is run.
}
n'oubliez pas qu'Internet Explorer 8 ne comprend pas indexOf
. Mais si personne de vos utilisateurs n'utilise ie8 (Google Analytics vous le dirait), omettez cette réponse . solution possible pour corriger ie8: Comment réparer Array indexOf () en JavaScript pour les navigateurs Internet Explorer
utilisez toujours indexOf
pour l'existence de sous-chaînes et match
uniquement lorsque vous en avez réellement besoin. c'est-à-dire que si vous recherchiez Wordsrc
dans une chaîne pouvant également contenir altsrc
, alors aString.match(/\bsrc\b/)
est en effet plus approprié.
Voici tous les moyens possibles (relativement) de rechercher une chaîne
// 1. includes (introduit dans ES6)
var string = "string to search for substring",
substring = "sea";
string.includes(substring);
// 2. string.indexOf
var string = "string to search for substring",
substring = "sea";
string.indexOf(substring) !== -1;
// 3. RegExp: test
var string = "string to search for substring",
expr = /sea/; // no quotes here
expr.test(string);
// 4. string.match
var string = "string to search for substring",
expr = "/sea/";
string.match(expr);
// 5. string.search
var string = "string to search for substring",
expr = "/sea/";
string.search(expr);
Voici une réponse: https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
Les repères semblent être tordus spécialement pour es6 comprend, lisez les commentaires.
si vous n'avez pas besoin des allumettes. => Soit vous avez besoin de regex et utilisez donc test. Sinon es6 inclut ou indexOf. Toujours test vs indexOf sont proches.
Ils semblent être les mêmes: https://jsperf.com/array-indexof-vs-includes/4 (si c'était différent, ce serait étrange, ils fonctionnent généralement de la même manière, à l'exception des différences qu'ils exposent vérifie ça )
Et pour mon propre test de référence. le voici http://jsben.ch/fFnA0 Vous pouvez le tester (cela dépend du navigateur) [plusieurs fois] voici comment il s’est comporté (plusieurs exécutions indexOf et comprenant un temps sur l’autre et ils sont proches). Donc, ils sont les mêmes. [ici en utilisant la même plate-forme de test que l'article ci-dessus].
Et ici pour la version longue (8 fois plus longue) http://jsben.ch/wSBA2
Testé à la fois chrome et firefox, même chose.
Remarquez que jsben.ch ne gère pas le dépassement de mémoire (ou qu'il limite correctement. Il ne montre aucun message). Le résultat peut donc être erroné si vous ajoutez plus de 8 duplications de texte (8 fonctionnent correctement). Mais la conclusion est que pour un très grand texte, les trois fonctionnent de la même manière Sinon, pour indexOf et includes sont les mêmes et testent un peu plus lentement. ou Peut être identique à ce qu'il semblait en chrome (firefox 60, il est plus lent).
Avis avec jsben.ch: ne paniquez pas si vous obtenez un résultat incohérent. Essayez différentes heures et voyez si elles sont cohérentes ou non. Changer de navigateur, parfois ils se trompent complètement. Bug ou mauvaise gestion de la mémoire. Ou quelque chose.
ex:
Ici aussi, ma référence sur jsperf (meilleurs détails et gestion des graphiques pour plusieurs navigateurs)
(le dessus est chrome)
texte normalhttps://jsperf.com/indexof-vs-includes-vs-test-2019
resume: includes et indexOf ont les mêmes performances. test plus lent.
(semble tous les trois effectuer la même chose en chrom)
Texte long (12 fois plus longtemps que la normale) https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume: Tous les trois font la même chose. (chrome et firefox)
très courte chaînehttps://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume: includes et indexOf effectuent la même chose et testent plus lentement.
Remarque: à propos de la référence ci-dessus. Pour la chaîne very short, la version (jsperf) contenait une grosse erreur pour chrome. Voyant à mes yeux. environ 60 échantillons ont été exécutés pour les deux indexOf et incluent de la même manière (répété beaucoup de temps). Et testez un peu moins et si lentement… .. ne vous laissez pas berner par le mauvais graphique. C'est clairement faux. Même travail de test ok pour firefox, c'est sûrement un bug.
Voici l'illustration: (la première image était le test sur firefox) waaaa. Soudain indexOf est devenu superman. Mais comme je l'ai dit, j'ai fait le test et examiné le nombre d'échantillons, il était d'environ 60. Les deux indexOf et comprend et ils ont effectué la même chose. Un bug sur jspref. Sauf pour celui-ci (peut-être à cause d'un problème lié à la restriction de mémoire), tout le reste était cohérent, cela donne plus de détails. Et vous voyez combien de simples se produisent en temps réel.
indexOf vs includes => Même performance
test => peut être plus lent pour les chaînes courtes ou le texte. Et pareil pour les textes longs. Et il est logique que le moteur regex ajoute une surcharge. En chrome, il semblait que ça n'avait pas d'importance.