检查字符串是否以某个内容开头?

291

我知道可以像 ^= 这样做来检查一个ID是否以某个字符开头,我曾尝试在这方面使用它,但并没有成功。基本上,我正在检索一个URL,并希望为路径名以特定方式开头的元素设置一个类。

例如:

var pathname = window.location.pathname;  //gives me /sub/1/train/yonks/459087

我希望能够针对以/sub/1开头的每个路径,为一个元素设置一个类:

if (pathname ^= '/sub/1') {  //this didn't work... 
        ... 

1
/^\/sub\/1.*$/gi.test(pathname) 将返回一个布尔值作为谓词。 - Downhillski
7
如果你像我一样6年后来到这里,那么原始和重复的Javascript StartsWith帖子提供了一个非常简洁的答案,使用ECMAScript 6的startWith()函数,看起来性能最佳。请注意,这里只是翻译,不包含解释或其他内容。 - theFreedomBanana
1
或者从非常详细的关于性能和“不要修改不属于自己的对象!”的讨论中阐述 - 也许像这样? if (pathname.indexOf('/sub/1') === 0) {//执行操作。} - Der Zinger
6个回答

395

18
-1: 创建了一个额外的、多余的字符串。 - user1071136
9
这是一个测试用例链接:http://jsperf.com/starts-with/2。在我的机器上(使用V8引擎),substring方法似乎是最快的。 - Pijusn
23
可以将代码改为如下更通用的形式:var x = "/sub/1"; if (pathname.indexOf(x) === 0) { // ... };这样,你就不需要知道 x 的长度,因为它可能会改变。 - user843337
创建一个新字符串并不理想,最好的方法可能是使用charAt,如果charAt本身不会创建一个新字符串 :) - Martijn Scheffer
我认为值得注意的是它正在创建一个字符串,但我不认为它值得被投票否决,因为没有明显更好的替代方案,并且我敢打赌,在大多数情况下,创建冗余字符串不会成为值得担心的问题。 - rooby

192
String.prototype.startsWith = function(needle)
{
    return this.indexOf(needle) === 0;
};

11
请参考这里的评论,了解不使用这种实现方式的有效原因:http://stackoverflow.com/a/1978419/560287 - John Magnolia
3
这是比标记为答案的那个更完美的答案(关于某事的indexOf)。 - Dilhan Jayathilake
15
如果出现“false”的情况,这个函数的性能将取决于要检查的字符串长度,这不符合此用例的预期行为。 - Daniel Alder
1
在我看来,这不仅是正确的答案,而且是在内存使用和速度方面最正确的答案。它也很易读,但请记住不要修改您不拥有的对象(或尽量避免这样做)。 - Florian Leitgeb
1
请不要修改标准对象。这不是最佳实践。 - kashesandr
显示剩余3条评论

88

你也可以使用string.match()和一个正则表达式来实现:

if(pathname.match(/^\/sub\/1/)) { // you need to escape the slashes
string.match() 如果找到匹配的子字符串,将返回一个数组,否则返回null

有没有办法在表达式中动态插入url字符串?例如,转义url中的/字符? - Tjorriemorrie
1
@Tjorriemorrie 你可以使用 RegEx 类来实现这个功能,例如 var reUrlTester = new RegEx(your_url_string); 如果(reUrlTester.test(url)) { // 使用 test 函数来检查 url 是否匹配。 - Cros
@Cros Err,你在那里犯了个拼写错误,类名实际上是"RegExp",所以应该是:var matcher = new RegExp(expected);if(matcher.test(actual)){ return true } - Kzqai
虽然这样做可以起作用,但如果没有必要,请尽量避免使用正则表达式。事实上,正则表达式函数比它们的等效字面字符串函数慢得多。实际上,一些官方文档网站甚至告诉你尽可能避免使用它(例如,我认为php.net就是这样)。我建议使用indexOf()或substr()解决方案。 - Byson
match 返回一个包含匹配字符串的数组,而不是匹配的字符串本身。请参阅 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/match - Trindaz

41

一个更加可重复使用的函数:

beginsWith = function(needle, haystack){
    return (haystack.substr(0, needle.length) == needle);
}

26

首先,让我们扩展字符串对象。感谢Ricardo Peres提供的原型,我认为在增加可读性方面使用变量'string'比'needle'更好。

String.prototype.beginsWith = function (string) {
    return(this.indexOf(string) === 0);
};

然后你可以像这样使用它。注意!这会使代码变得极易读懂。

var pathname = window.location.pathname;
if (pathname.beginsWith('/sub/1')) {
    // Do stuff here
}

5
并没有真正添加任何东西。 - ratbum
在我看来,如果 indexOf 在字符串的开头没有找到立即匹配项,则会搜索整个字符串:因此,对于要搜索的非常长的字符串,它的效率会降低。 - willy wonka

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接