291

I know that I can do like ^= to see if an id starts with something, and I tried using that for this, but it didn't work. Basically, I'm retrieving a URL and I want to set a class for an element for path names that start in a certain way.

Example:

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

I want to make sure that for every path that starts with /sub/1, I can set a class for an element:

if (pathname ^= '/sub/1') {  //this didn't work... 
        ... 
informatik01
  • 16,038
  • 10
  • 74
  • 104
n00b0101
  • 6,863
  • 17
  • 42
  • 36
  • 1
    `/^\/sub\/1.*$/gi.test(pathname)` will return a boolean as predicate. – Downhillski Jun 23 '16 at 14:12
  • 7
    If you're coming here 6 years later (as myself) the [original & duplicated post Javascript StartsWith](http://stackoverflow.com/questions/646628/how-to-check-if-a-string-startswith-another-string) provides a very neat answer, using Ecmascript 6 startWith() function, that seems to have the best performances. – theFreedomBanana Sep 22 '16 at 07:36
  • 1
    Or elaborating from a very detailed discussions 'bout performance and `Thou shall not modify Objects not owned!` - something like this maybe? `if (pathname.indexOf('/sub/1') === 0) {//Do.}` – Der Zinger Nov 14 '18 at 14:21

6 Answers6

395

Use stringObject.substring

if (pathname.substring(0, 6) == "/sub/1") {
    // ...
}
Pijusn
  • 11,025
  • 7
  • 57
  • 76
Philip Reynolds
  • 9,364
  • 3
  • 30
  • 37
  • 18
    -1: creates an additional, redundant string. – user1071136 Jan 17 '13 at 19:57
  • 9
    Here is a test case for this: http://jsperf.com/starts-with/2 . Substring method appears to be the fastest on my machine (with V8). – Pijusn Jul 20 '13 at 19:34
  • 23
    This can be made more generic like so: `var x = "/sub/1"; if (pathname.substring(0, x.length) === x) { // ... };`. This way you're no longer reliant on knowing the length of `x` as it may change. –  Jul 12 '15 at 11:34
  • creates a new string, so it's not ideal, best method is probably to use charAt, if charAt doesn't create a new string itself :) – Martijn Scheffer Jul 20 '16 at 16:23
  • I would say that it is worth noting that it is creating a string but I don't think it's worth down voting since there isn't an abundance of clearly better alternatives and I would bet that in most cases the creation of a redundant string is not going to be a problem worth worrying about. – rooby Jun 10 '20 at 08:14
192
String.prototype.startsWith = function(needle)
{
    return this.indexOf(needle) === 0;
};
Ricardo Peres
  • 13,724
  • 5
  • 57
  • 74
  • 11
    -1 see comments here for a valid reason not to use this type of implementation: http://stackoverflow.com/a/1978419/560287 – John Magnolia Mar 30 '13 at 23:46
  • 3
    This is the perfect answer (indexOf thing) than the one which is marked as the answer. – Dilhan Jayathilake Aug 07 '13 at 00:05
  • This sucks, I'm with @JohnMagnolia. Use the regular expression: `/^\/sub\/1/`. – Adam McArthur Oct 03 '14 at 15:06
  • 15
    In case of `false`, the performance of this function depends on the length of the string you want to check, which is not expected bahaviour for this use case – Daniel Alder Dec 29 '14 at 22:03
  • 1
    In my opnion not the only correct, but the most correct answer in terms of memory usage and speed. And it is also readable, but keep in mind to not modify objects you do not own (or just try to avoid it). – Florian Leitgeb Jun 29 '15 at 13:19
  • The advantage of using a separate function for this is that the implementation - using indexOf, or RegExp, or substring - can be changed if one way is found to be faster than another. – Craig S. Anderson Mar 15 '16 at 18:09
  • 1
    this is the slow way to do this, comparison will continue throughout the whole string, i would not use this if this methods gets called a lot. – Martijn Scheffer Jul 20 '16 at 16:23
  • 1
    Please don't modify the standard objects. It's not the best practice. – kashesandr Aug 03 '16 at 15:32
88

You can use string.match() and a regular expression for this too:

if(pathname.match(/^\/sub\/1/)) { // you need to escape the slashes

string.match() will return an array of matching substrings if found, otherwise null.

Jonathan Vanasco
  • 15,111
  • 10
  • 48
  • 72
Cros
  • 4,367
  • 9
  • 41
  • 47
  • Is there any way to dynamically insert a url string in the expr? e.g. escaping the /'s in the url? – Tjorriemorrie Jul 11 '13 at 13:04
  • 1
    @Tjorriemorrie You can use the RegEx class to accomplish this, like var reUrlTester = new RegEx(your_url_string); if(reUrlTester.test(url)) { // use the test-function to see if the url matches. – Cros Aug 05 '13 at 11:02
  • @Cros Err, you made a typo there, the class is actually "RegExp", so that should be: `var matcher = new RegExp(expected);if(matcher.test(actual)){ return true }` – Kzqai Dec 19 '14 at 18:37
  • While this will work, try to avoid using RegEx if not strictly necessary. It's just a plain fact that RegEx functions are slower than their equivalent literal string functions. So much slower in fact that some official documentation websites actually tell you to avoid it if possible (I think php.net does, for example). I'd recommend the indexOf() or substr() solutions. – Byson Dec 22 '14 at 14:59
  • match returns an array with matching strings, not the matching string. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match – Trindaz Jan 29 '15 at 16:51
41

A little more reusable function:

beginsWith = function(needle, haystack){
    return (haystack.substr(0, needle.length) == needle);
}
Mahn
  • 16,261
  • 16
  • 62
  • 78
RobKohr
  • 6,611
  • 7
  • 48
  • 69
26

First, lets extend the string object. Thanks to Ricardo Peres for the prototype, I think using the variable 'string' works better than 'needle' in the context of making it more readable.

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

Then you use it like this. Caution! Makes the code extremely readable.

var pathname = window.location.pathname;
if (pathname.beginsWith('/sub/1')) {
    // Do stuff here
}
Daedalus
  • 7,586
  • 5
  • 36
  • 61
Tim
  • 277
  • 3
  • 2
2

Have a look at JavaScript substring() method.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Piotr Rochala
  • 7,748
  • 2
  • 33
  • 54