JavaScript: indexOf vs. Match when Searching Strings?
除了可读性之外,使用之间是否存在任何可辨别的差异(可能性能)
1 | str.indexOf("src") |
和
1 | str.match(/src/) |
我个人更喜欢
编辑:
我应该在一开始就说过,这是用于执行部分普通字符串匹配的函数(在JQuery的类属性中获取标识符),而不是使用通配符等进行完整的正则表达式搜索。
1 | class='redBorder DisablesGuiClass-2345-2d73-83hf-8293' |
所以它的区别在于:
1 | string.indexOf('DisablesGuiClass-'); |
VS
1 | string.match(/DisablesGuiClass-/) |
RegExp确实比indexOf慢(你可以在这里看到它),虽然通常这应该不是问题。使用RegExp,您还必须确保正确转义字符串,这是一个需要考虑的额外事项。
抛开这两个问题,如果两个工具完全符合您的需求,为什么不选择更简单的工具呢?
你的比较可能不完全公平。
在您的情况下,如果您要查找逐字字符串,
1 | indexOf('bar') |
将在
1 | match(/\bbar\b/) |
只有当它不是较长单词的一部分时才会匹配
正如您在评论中看到的那样,已经进行了一些比较,表明正则表达式可能比
如果您尝试不区分大小写地搜索子字符串出现,则
点击这里 - http://jsperf.com/regexp-vs-indexof/152
你问是否应该首选
问题是,在技术上没有一个设计用于提出更简单的问题"字符串是否包含子字符串?"有明确设计的东西:
1 | var doesStringContainTarget = /target/.test(str); |
使用
理论上,当你只是搜索一些纯文本时,使用
如果您更喜欢
对于它的价值,我同意你的同事:我在搜索普通字符串时使用
性能方面
Will an integer index suffice or do I
need the functionality of a RegExp
match result?
这里搜索字符串的所有可能方式(相对)
// 1.包括(在ES6中引入)
1 2 3 | var string ="string to search for substring", substring ="sea"; string.includes(substring); |
// 2. string.indexOf
1 2 3 | var string ="string to search for substring", substring ="sea"; string.indexOf(substring) !== -1; |
// 3. RegExp:测试
1 2 3 | var string ="string to search for substring", expr = /sea/; // no quotes here expr.test(string); |
// 4. string.match
1 2 3 | var string ="string to search for substring", expr ="/sea/"; string.match(expr); |
// 5。 string.search
1 2 3 | var string ="string to search for substring", expr ="/sea/"; string.search(expr); |
这里有一个src:https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
基准似乎特别针对es6包括扭曲,阅读评论。
简历中:
如果你不需要比赛。
=>你需要正则表达式,所以使用测试。否则es6包含或indexOf。仍然测试与indexOf接近。
对于includes vs indexOf:
它们看起来是一样的:https://jsperf.com/array-indexof-vs-includes/4(如果它不同它会很奇怪,它们大多数表现相同,除了它们暴露的差异检查这个)
并为我自己的基准测试。这是http://jsben.ch/fFnA0
你可以测试它(它取决于浏览器)[多次测试]
在这里它是如何执行的(多次运行indexOf并包括一个击败另一个,它们很接近)。所以他们是一样的。 [这里使用与上述文章相同的测试平台]。
这里是一个长文本版本(8倍长)
http://jsben.ch/wSBA2
测试了chrome和firefox,同样的事情。
注意jsben.ch不处理内存溢出(或者没有正确限制。它没有显示任何消息)所以如果添加8个以上的文本复制(8个工作正常),结果可能会出错。但结论是对于非常大的文本,所有三个都以相同的方式执行。否则为简短的indexOf和包含相同,测试速度稍慢。或者可以与chrome中的相同(firefox 60它更慢)。
请注意jsben.ch:如果得到不一致的结果,请不要惊慌失措。尝试不同的时间,看看它是否一致。更改浏览器,有时他们只是完全错误。内存错误或处理不当。或者其他的东西。
例如:
这也是我对jsperf的基准测试(更好的细节,并处理多个浏览器的图形)
(顶部是铬)
普通文字
https://jsperf.com/indexof-vs-includes-vs-test-2019
resume:includes和indexOf具有相同的性能。测试慢一点。
(似乎所有三个人在铬中表现相同)
长文本(比正常长12倍)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
简历:三者都表现相同。 (chrome和firefox)
非常短的字符串
https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume:includes和indexOf执行相同并且测试速度较慢。
注意:关于上面的基准。对于非常短的字符串版本(jsperf),chrome有一个很大的错误。看着我的眼睛。 indexOf运行大约60个样本并包含相同的方式(重复很多次)。并且测试少一点,慢一点。
不要被错误的图表所迷惑。这显然是错的。同样的测试工作对于firefox来说,肯定是一个bug。
这里插图:(第一张图片是对firefox的测试)
waaaa。突然索引成为超人。但正如我所说,我做了测试,并查看了大约60个样本的数量。无论是indexOf还是包括,他们都表现相同。 jspref上的一个错误。除了这个(可能是因为内存限制相关的问题)所有其余的都是一致的,它提供了更多的细节。你会看到有多少简单的实时发生。
最后的简历
indexOf vs includes =>性能相同
对于短字符串或文本,test =>可能会更慢。长文本也一样。这对正则表达式引擎添加的开销很有意义。在Chrome中它似乎根本没关系。
返回值不同
除了其他答案所解决的性能影响之外,重要的是要注意每种方法的返回值是不同的;所以这些方法不能仅仅在不改变逻辑的情况下被替换。
返回值
The index within the calling
String object of the first occurrence of the specified value, starting the search atfromIndex .
Returns-1 if the value is not found.
返回值
An Array containing the entire match result and any parentheses-captured matched results.
Returnsnull if there were no matches.
因为如果调用字符串以指定值开头,
例如:
鉴于这门课......
1 | class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder' |
...每个的返回值会有所不同:
1 2 3 4 | // returns `0`, evaluates to `false` if (string.indexOf('DisablesGuiClass-')) { … // this block is skipped. } |
与
1 2 3 4 | // returns `["DisablesGuiClass-"]`, evaluates to `true` if (string.match(/DisablesGuiClass-/)) { … // this block is run. } |
使用
1 2 3 4 | if (string.indexOf('DisablesGuiClass-') !== -1) { // ^returns `0` ^evaluates to `true` … // this block is run. } |
记得Internet Explorer 8不理解
但是,如果您的用户中没有人使用ie8(谷歌分析会告诉你),而不是省略这个答案。
修复ie8的可能解决方案:
如何在JavaScript中为Internet Explorer浏览器修复Array indexOf()
只有当你真正需要它时,才总是使用