How to check if a string “StartsWith” another stri

2018-12-31 02:42发布

How would I write the equivalent of C#'s String.StartsWith in JavaScript?

var haystack = 'hello world';
var needle = 'he';

haystack.startsWith(needle) == true

Note: This is an old question, and as pointed out in the comments ECMAScript 2015 (ES6) introduced the .startsWith method. However, at the time of writing this update (2015) browser support is far from complete.

16条回答
查无此人
2楼-- · 2018-12-31 02:58

I recently asked myself the same question.
There are multiple possible solutions, here are 3 valid ones:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0 (added after seeing Mark Byers's answer)
  • using a loop:

    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;
    }
    

I haven't come across the last solution which makes uses of a loop.
Surprisingly this solution outperforms the first 3 by a significant margin.
Here is the jsperf test I performed to reach this conclusion: http://jsperf.com/startswith2/2

Peace

ps: ecmascript 6 (harmony) introduces a native startsWith method for strings.
Just think how much time would have been saved if they had thought of including this much needed method in the initial version itself.

Update

As Steve pointed out (the first comment on this answer), the above custom function will throw an error if the given prefix is shorter than the whole string. He has fixed that and added a loop optimization which can be viewed at http://jsperf.com/startswith2/4.

Note that there are 2 loop optimizations which Steve included, the first of the two showed better performance, thus I will post that code below:

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;
}
查看更多
人间绝色
3楼-- · 2018-12-31 03:00

Another alternative with .lastIndexOf:

haystack.lastIndexOf(needle, 0) === 0

This looks backwards through haystack for an occurrence of needle starting from index 0 of haystack. In other words, it only checks if haystack starts with needle.

In principle, this should have performance advantages over some other approaches:

  • It doesn't search the entire haystack.
  • It doesn't create a new temporary string and then immediately discard it.
查看更多
深知你不懂我心
4楼-- · 2018-12-31 03:00

The best performant solution is to stop using library calls and just recognize that you're working with two arrays. A hand-rolled implementation is both short and also faster than every other solution I've seen here.

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;
}

For performance comparisons (success and failure), see http://jsperf.com/startswith2/4. (Make sure you check for later versions that may have trumped mine.)

查看更多
柔情千种
5楼-- · 2018-12-31 03:00

If you are working with startsWith() and endsWith() then you have to be careful about leading spaces. Here is a complete example:

var str1 = " Your String Value Here.!! "; // Starts & ends with spaces    
if (str1.startsWith("Your")) { }  // returns FALSE due to the leading spaces…
if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces…

var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`.
if (str2.startsWith("Your")) { }  // returns TRUE
if (str2.endsWith("Here.!!")) { } // returns TRUE
查看更多
明月照影归
6楼-- · 2018-12-31 03:05

You can use ECMAScript 6's String.prototype.startsWith() method, but it's not yet supported in all browsers. You'll want to use a shim/polyfill to add it on browsers that don't support it. Creating an implementation that complies with all the details laid out in the spec is a little complicated, and the version defined in this answer won't do; if you want a faithful shim, use either:

Once you've shimmed the method (or if you're only supporting browsers and JavaScript engines that already have it), you can use it like this:

"Hello World!".startsWith("He"); // true

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false
查看更多
萌妹纸的霸气范
7楼-- · 2018-12-31 03:06

Since this is so popular I think it is worth pointing out that there is an implementation for this method in ECMA 6 and in preparation for that one should use the 'official' polyfill in order to prevent future problems and tears.

Luckily the experts at Mozilla provide us with one:

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;
    };
}

Please note that this has the advantage of getting gracefully ignored on transition to ECMA 6.

查看更多
登录 后发表回答