我如何String.StartsWith
在JavaScript中编写等效的C#?
var haystack = 'hello world'; var needle = 'he'; haystack.startsWith(needle) == true
注意:这是一个老问题,正如评论中指出的ECMAScript 2015(ES6)引入了该.startsWith
方法.但是,在撰写此更新时(2015年),浏览器支持还远未完成.
您可以使用ECMAScript 6的String.prototype.startsWith()
方法,但并不是所有浏览器都支持它.您将需要使用填充/填充将其添加到不支持它的浏览器上.创建符合规范中列出的所有细节的实现有点复杂,并且此答案中定义的版本不会这样做; 如果你想要忠实的垫片,请使用:
Matthias Bynens的String.prototype.startsWith
垫片,或者
该ES6-垫片,其衬层尽可能多的ES6规范越好,包括String.prototype.startsWith
.
一旦你填充了方法(或者如果你只支持已经拥有它的浏览器和JavaScript引擎),你可以像这样使用它:
"Hello World!".startsWith("He"); // true var haystack = "Hello world"; var prefix = 'orl'; haystack.startsWith(prefix); // false
另一种选择.lastIndexOf
:
haystack.lastIndexOf(needle, 0) === 0
这看起来haystack
是needle
从索引0
的开始出现的haystack
.换句话说,它只检查是否haystack
以needle
.
原则上,这应该比其他一些方法具有性能优势:
它不会搜索整个haystack
.
它不会创建新的临时字符串,然后立即丢弃它.
data.substring(0, input.length) === input
没有辅助函数,只需使用正则表达式的.test
方法:
/^He/.test('Hello world')
要使用动态字符串而不是硬编码字符串(假设字符串不包含任何正则表达式控制字符):
new RegExp('^' + needle).test(haystack)
你应该看看Javascript中是否有RegExp.escape函数?如果存在正则表达式控制字符出现在字符串中的可能性.
最佳方案:
function startsWith(str, word) { return str.lastIndexOf(word, 0) === 0; }
如果你需要的话,这里有结果:
startsWith("aaa", "a") true startsWith("aaa", "ab") false startsWith("abc", "abc") true startsWith("abc", "c") false startsWith("abc", "a") true startsWith("abc", "ba") false startsWith("abc", "ab") true
对于那些喜欢将其原型化为String的人:
function endsWith(str, word) { return str.indexOf(word, str.length - word.length) !== -1; }
用法:
String.prototype.startsWith || (String.prototype.startsWith = function(word) { return this.lastIndexOf(word, 0) === 0; }); String.prototype.endsWith || (String.prototype.endsWith = function(word) { return this.indexOf(word, this.length - word.length) !== -1; });
我只是想加上我对此的看法.
我想我们可以像这样使用:
var haystack = 'hello world'; var needle = 'he'; if (haystack.indexOf(needle) == 0) { // Code if string starts with this substring }
以下是CMS解决方案的一个小改进:
if(!String.prototype.startsWith){ String.prototype.startsWith = function (str) { return !this.indexOf(str); } } "Hello World!".startsWith("He"); // true var data = "Hello world"; var input = 'He'; data.startsWith(input); // true
检查该函数是否已存在,以防将来的浏览器在本机代码中实现它,或者是否由另一个库实现.例如,Prototype Library已经实现了这个功能.
使用!
比=== 0
不可读更快,更简洁.
还可以看看underscore.string.js.它附带了一堆有用的字符串测试和操作方法,包括一个startsWith
方法.来自文档:
以..开始
_.startsWith(string, starts)
此方法检查是否
string
以starts
._("image.gif").startsWith("image") => true
我最近问自己同样的问题.
有多种可能的解决方案,这里有3个有效的解决方案:
s.indexOf(starter) === 0
s.substr(0,starter.length) === starter
s.lastIndexOf(starter, 0) === 0
(看过Mark Byers的回答后补充说)
使用循环:
function startsWith(s,starter) { for (var i = 0,cur_c; i < starter.length; i++) { cur_c = starter[i]; if (s[i] !== starter[i]) { return false; } } return true; }
我没有遇到使用循环的最后一个解决方案.
令人惊讶的是,这个解决方案的优势明显优于前3个.
这是我为达到这个结论而进行的jsperf测试:http://jsperf.com/startswith2/2
和平
ps:ecmascript 6(和谐)startsWith
为字符串引入了一种原生方法.
想想如果他们想到在初始版本中包含这个非常需要的方法,那么会节省多少时间.
更新
正如Steve指出的那样(对这个答案的第一个评论),如果给定的前缀比整个字符串短,上面的自定义函数将抛出一个错误.他修复了这个问题,并添加了一个循环优化,可以在http://jsperf.com/startswith2/4上查看.
请注意,Steve包含了2个循环优化,两个中的第一个表现出更好的性能,因此我将在下面发布以下代码:
function startsWith2(str, prefix) { if (str.length < prefix.length) return false; for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i) continue; return i < 0; }
由于这是如此受欢迎,我认为值得指出的是,这种方法在ECMA 6中有实施,并且为了准备,应该使用"官方"polyfill以防止将来出现问题和眼泪.
幸运的是,Mozilla的专家为我们提供了一个:
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; }
请注意,这有利于在过渡到ECMA 6时被优雅地忽略.
最佳性能解决方案是停止使用库调用,并且只是认识到您正在使用两个数组.手动实现既简短又快于我在此处看到的所有其他解决方案.
function startsWith2(str, prefix) { if (str.length < prefix.length) return false; for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i) continue; return i < 0; }
有关性能比较(成功与失败),请参阅http://jsperf.com/startswith2/4.(确保检查可能胜过我的更高版本.)