How to check whether a string contains a substring in JavaScript?

7 435

1 324

Usually I would expect a String.contains() method, but there doesn't seem to be one.

What is a reasonable way to check for this?


Posted 2009-11-24T13:04:29.157

Reputation: 9 199


It's easy with the indexOf method, you can see a tutorial of indexOf and substring here:

– Triton Man – 2015-03-30T17:53:40.633


possible duplicate of JQuery string contains check

– Saswat – 2015-08-18T11:14:39.297


you can see speed of r.indexOf(s) !== -1; fastest than others.

– Sherali Turdiyev – 2015-10-01T05:37:59.760

you can try this "foo bar".match('oo') ? console.log("contained") : console.log("not contained"); – Alejandro Vales – 2016-05-24T10:51:45.367


Finally! There is an includes() method for strings in ECMA6. Supported by everyone except IE. A good polyfill is available in Mozilla's docs:

– K48 – 2016-10-03T11:49:09.803


Here a benchmark for the most common ways to check if a string is in a string:

– EscapeNetscape – 2016-10-26T09:38:41.063


Video covering the best of the options below in < 5 minutes, here:

– ssmith – 2016-12-14T16:19:20.133

A very useful and widely used website is W3Schools, see - "This section contains a complete JavaScript reference documentation."

– Edward – 2017-08-20T12:21:46.563

TypeScript incorporate string.container actually – freedeveloper – 2018-03-08T05:37:17.593


11 966

Here is a list of current possibilities:

1. (ES6) includesgo to answer

var string = "foo",
    substring = "oo";

2. ES5 and older indexOf

var string = "foo",
    substring = "oo";
string.indexOf(substring) !== -1;

String.prototype.indexOf returns the position of the string in the other string. If not found, it will return -1.

3. searchgo to answer

var string = "foo",
    expr = /oo/;;

4. lodash includesgo to answer

var string = "foo",
    substring = "oo";
_.includes(string, substring);

5. RegExpgo to answer

var string = "foo",
    expr = /oo/;  // no quotes here

6. Matchgo to answer

var string = "foo",
    expr = /oo/;

Performance tests are showing that indexOf might be the best choice, if it comes to a point where speed matters.

Fabien Ménager

Posted 2009-11-24T13:04:29.157

Reputation: 133 393

14@MathiasBynens Actually not, since if it's the first letter it will return the falsy 0, even though it contains the value. Just test in any browser console: 'hello'.indexOf('h') – Seb Nilsson – 2012-02-07T17:56:41.867

63@SebNilsson You forgot to include the ~ operator that I suggested in my comment. ~'hello'.indexOf('h'); // -1, which is truthy, but ~'hello'.indexOf('x'); // 0, which is falsy. – Mathias Bynens – 2012-02-08T08:05:24.087

7does this work on IE ? – isJustMe – 2012-02-14T16:16:58.517

36@pramodc84 that link refers to the Array object indexOf method not to the String object method – gion_13 – 2012-04-26T13:26:15.713

1I've written a small function that encapsulates this kind of behaviour (see below) – ndemoreau – 2012-06-11T19:37:38.677

11I want to give a little addition to make it non-case-sensitive which is beneficial for me: var s = "foo",t = "oo";alert(s.toLowerCase().indexOf(t.toLowerCase()) != -1); – efirat – 2012-10-03T14:09:25.283

6@pramodc84, that's Array.prototype.indexOf(); String.prototype.indexOf() is available everywhere. – cbrandolino – 2012-11-28T09:29:56.437

8@boxed That very much depends upon why you're writing the code and what tricks you're using. Sometimes tricks like this are necessary to make code faster/more memory efficient etc. Readability isn't everything. – Luke – 2012-12-18T16:44:38.343

5Maybe in 2016, if ECMAScript 6 is widely adopted & implemented, we'll be able to do that! :P "orange juice".contains("juice") – Lucas Pottersky – 2013-01-10T21:34:25.860

12@Luke You are right. It should be noted for the js (or development) newbie that as a general practice, preferring readability/maintainability over fine tuning is probably best. In cases where tuning is necessary explanatory comments in an uncompressed version of ones code are invaluable for pointing out what's going on and why one is being 'tricky'. – jinglesthula – 2013-11-26T21:08:02.400

3Why !== ? I prefer != . – Nicolas Barbulesco – 2013-11-29T15:23:17.723


@NicolasBarbulesco Automagically casting truthy/falsey values can be very dangerous if you don't know exactly what you're doing. See this post for a more thorough explanation of the difference in these two comparison operators.

– Bucket – 2013-12-05T16:28:22.220

6@DesertIvy — In the light of this, I confirm that I prefer !=, not !==. Here, I don't want to test the types, I want to test only the values. Moreover, != is clear whereas !== is, at first, mysterious. – Nicolas Barbulesco – 2013-12-06T13:00:11.323

71@NicolasBarbulesco I am confident that all of the people who look at my code will know that [["\t\n 987654321e-400"]] === 0 is false. I am much less confident that everyone who looks at my code will know that [["\t\n 987654321e-432"]] == 0 is true. – kybernetikos – 2013-12-11T15:48:50.157

19Blindly following the "always use !==" rule is not the answer here, you can safely use != if you know that you are comparing two numbers. -1 is NOT falsey and therefore != is always appropriate in this specific instance. – gcochard – 2013-12-11T16:35:45.713

12@Greg Amen! I can't stand people who don't want to understand proper JS comparison rules and want to blindly follow the "always use strict comparison" rule (probably from Crockford). Strict comparison can cause bugs too. – Juan Mendes – 2014-02-11T18:58:55.293

10The squiggle (~str.indexOf()) could be considered idiomatic by now. Writing idiomatic JavaScript is good. – dalgard – 2014-04-25T14:08:59.300

1@DustinWyatt I don't think it's extreme, it causes unnecessary extra code just because people who don't want to understand the difference. Specially since always using === is not the always the right answer, there are cases when you do need == and you'd need a lot of extra code to make code comply. It's the nature of a dynamic language. – Juan Mendes – 2014-05-08T17:35:21.447

7@dalgard It's idiomatic? Maybe, but I find it confusing – Juan Mendes – 2014-05-08T17:37:15.277

1But I thought Javascript doesn't have true integers. So -1 is represented as all 1's in floating point? – huggie – 2014-06-08T07:13:57.407

2@huggie: I find it hard to state categorically that "Javascript doesn't have true integers"; I certainly understand what was motivating that statement, but I find it a bit simplistic. Regardless . . . in point of fact, JavaScript's ~ operates on 32-bit signed (two's-complement) integers. For example, ~3.7 evaluates to -4 (because an integer conversion takes 3.7 to 3). – ruakh – 2014-07-21T22:53:39.950

2@JuanMendes how does strict comparison cause bugs? – Klors – 2014-09-11T13:22:51.640

4@klors A common example is a numeric ID that may passed in as a string or as a number (because it came from the query string, maybe). It's not that you can't work around it, but you need extra code and if you blindly use === it will only work for one case, so you'd need to do the conversion yourself. Using if (id == myId) will do the conversion for you. – Juan Mendes – 2014-09-11T15:33:45.433

2@JuanMendes ah, I thought you meant there was some problem with it, rather than that it might be misused – Klors – 2014-09-11T16:09:33.393

1+1 for the original answer of != (my preference, especially when safe), and I would +1 the editor that changed it to &gt; -1 to stop the edit skirmish (it wasn't quite a war...). – goodeye – 2014-11-11T01:58:19.173

Both "foo".indexOf("foo") and "foo".indexOf("") return 0. I find this confusing. Does anyone know why this is? – Adam – 2014-11-24T03:04:28.717


@Adam The first character in a string has an index of 0. That's where the substring "foo" first appears in "foo". It's also where "" first appears in "foo". (To use a physical-world metaphor, an empty string is thin enough to fit in between the opening quote and the first letter of "foo".) So, indexOf returns 0 in both cases.

– jkdev – 2014-12-23T07:51:20.537

@jkdev Sorry, that doesn't make much sense to me. I totally get that the first character of the string is at index 0, I totally don't get why an empty string should match anywhere, since the string we are trying to match is not empty. – Adam – 2014-12-24T22:03:10.997

1It isn't empty, but it has empty strings within it. – jkdev – 2014-12-24T22:13:19.140

It's kind of like in regular expressions with a word boundary, /\b/, or a non-word-boundary, /\B/ -- those aren't characters but they can fit in between characters, so to speak. – jkdev – 2014-12-24T22:16:08.777

When do you think it will be safe to use includes? – Vandervals – 2015-05-29T08:48:59.493

Use indexOf. Found out today .includes does not work on mobile Safari – ErikAGriffin – 2015-07-07T17:16:06.590


if .includes is not working for you, then use !!~ "foo".indexOf("foo"), It's the same/similar thing. search page there for indexOf or scroll down to includes for more information

– Val – 2015-08-26T10:49:54.453

@FabienMenager, can you update your answer so ES6 will be included? In ES6 we can use .includes wich makes .indexOf deprecated for a contains variant. – Schuere – 2016-02-17T10:02:58.877

I think @Val's suggestion of !!~"foo".indexOf("foo") is better if it is being stored to a variable for later use. Just using ~ will make the true values be negative numbers. In JS -1 is not as "truthy" as positive 1: if (-1) // True, if (-1 == true) // False, but if (1 == true) // True. – GreeKatrina – 2016-04-08T19:16:05.913

I just want to mention that the bitwise suggestion in the first comment is really not that readable--and is not "idiomatic"--so please only do that in situations where you need very short code. Also, I think always using strict comparison is smart and a good practice. The claim that it causes bugs begs the question. What bugs has it caused? On the other hand, I can think of plenty of bugs caused by unexpected results of the type conversion of ==. – Alex W – 2017-01-05T15:27:11.223

6I don't understand why indexOf is introduced as an "Outdated answer". It's still the best current answer, isn't it? – ChrisW – 2017-01-18T13:56:32.720

var string = "foo", expr= "/oo/"; expr.test(string); will no work, because regexp defined as a string. – degr – 2017-01-23T11:54:25.057

895@Steve indexOf always returns a number so there’s no need to use !==. If you want to save bytes, you could use ~'foo'.indexOf('oo') which returns a truthy value if the substring is found, and a falsy value (0) if it isn’t. – Mathias Bynens – 2011-07-07T11:00:50.293

includes should not appear in this list, or in very last position and with a big warning, since it's not compatible with IE and Opera. As an only ES6 method, it should not appear at all in my opinion. – jck – 2018-02-01T14:00:12.453

1@jck ES6 is JS. Why shouldn’t a native feature of JS be included in this answer? – J F – 2018-03-03T14:25:30.700

1I disagree with the use of '~'. Using a bitwise operator that results in a -1 numeric value which is defined as being the result when the string isn't found, being used as a 32 bit integer value and flipping the bits to get a 32 bit integer value of 0 which is then interpreted as a boolean false isn't worth saving a few bytes of code. I think you should only use bitwise operators when you are manipulating bits for a reason, not as a shortcut unless you are doing code golf. – Jason Goemaat – 2018-03-16T07:45:51.820

681For the curious: in two's compliment systems, -1 is represented in binary as all 1s (1111 1111 1111 1111 1111 1111 1111 1111 for 32 bit). The bitwise inverse (~) of this is all zeros, or just zero, and therefore falsy. That's why the squiggle trick works, and it is pretty bad-ass if I must say so myself. – Adam Tolley – 2011-09-14T21:36:26.620

It is not always true about performance. I ran the tests on different browsers and found that test results are not consistent. More importantly indexOf() doesn't out perform any other methods, especially the includes() method. includes() is more prominent and meaningful to use in this context. – Diablo – 2018-10-25T13:38:55.127


You can easily add a contains method to String with this statement:

String.prototype.contains = function(it) { return this.indexOf(it) != -1; };

Note: see the comments below for a valid argument for not using this. My advice: use your own judgement.


if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }

Avi Flax

Posted 2009-11-24T13:04:29.157

Reputation: 37 724

4if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; } else { alert ("Your code may now be broken! Check the definition of String.prototype.contains."); } – Vinko Vrsalovic – 2012-06-21T12:57:48.720

13Note that a String.prototype.contains method is in the process of being standardized, making this modification an even worse idea than it was when first answered. And it is precisely these sorts of modifications, made by unthinking web developers, that are making it such a pain to ship this new method in Firefox. (It's implemented in the latest nightly builds, and I think in Aurora builds. But it's unknown when it'll make it into a release, as there has been site breakage from the addition that must be laboriously resolved first.) – Jeff Walden – 2012-09-23T05:16:24.330

1@JeffWalden: I'm curious: what causes the breakage? – Dan Tao – 2013-08-30T22:05:38.320


The problem is the method here isn't compatible with the built-in method. Any code that assumes the built-in method semantics will be exposed (ads on the page, WordPress plugins, anything else), will get this, and will get nonsense behavior. See for a list of a bunch of sites that broke because MooTools 1.2.x implemented an incompatible String.prototype.contains (presumably by only conditionally patching, if there was no existing contains method), and the browser-provided version didn't behave like elements of the page expected.

– Jeff Walden – 2013-09-03T22:17:03.087


ECMAScript 6 includes String.prototype.contains

– rab – 2013-09-23T10:04:29.023

JSHint warns about overwriting prototypes of native objects.

– Niels Steenbeek – 2014-07-07T13:34:57.000

6-100 if I could. Don't do this. Ever. Others have explained some of the why. But a general principle is that if you make objects that LOOK like they're something else; someone will think they ARE something else. This is how to end up with a maintenance nightmare. Don't do this. Ever. – Dawood ibn Kareem – 2014-08-30T08:01:23.480

!= vs !== anyone? – ajndl – 2014-10-15T14:40:38.267

1There is absolutely nothing wrong with polyfilling the standards track .contains implementation with a typeof guard. It should simply be changed to String.prototype.indexOf.apply(this, arguments) !== -1 – Rich Remer – 2014-10-24T23:05:44.903

6ECMAScript 6 removed .contains because of invalid polyfills. It now contains .includes instead. – Benjamin Gruenbaum – 2015-01-20T10:56:38.443


Don't modify objects you don't own.

– zachleat – 2011-02-17T19:59:58.143

5I agree that that's a best practice in general, but I feel that it's generally OK for app-specific code. It'd be terrible for a library though. – Avi Flax – 2011-02-17T20:57:14.493

89@zachleat, that understandable in practice. But "foobar".contains("bar") would be a really useful exception to the rule. – ndbroadbent – 2011-02-22T09:50:33.150

81Eh, my preference would be to adapt my mental model to fit JavaScript and just use indexOf. It will make the code easier to understand for the next JavaScripter that comes along and has to read it. – zachleat – 2011-03-04T16:03:34.143

3I agree with @Zachleat. This is a cool concept, but I also think it's important to write code that will be understandable long after you're gone. ("contains" is easy to understand, but it's easy to get carried away and write your own language in JavaScript. It's great as a Computer Science exercise but horrible in a production environment). – jmort253 – 2011-04-01T15:42:15.073

It's no the best practice to modify such objects.. – kashesandr – 2017-01-24T16:43:22.310

77if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; } – Pavel Hodek – 2011-06-07T15:24:00.303

60I this it is preferrable to use this function if you are going to be using this kind of indexOf's frequently. @zachleat, I would disagree that using indexOf is more readable than contains. Contains describes what is happening, where to some indexOf() != -1 may not be so transparent. But to each their own, as long as you're consistant. – smdrager – 2011-07-11T14:03:54.037

Don't monkey patch browser objects. – mccambridge – 2018-06-01T15:14:15.283

4If you document your modifications and share them with the team then it's fine. It's simply a matter of discipline. If your team doesn't follow documentation then you'll have bigger issues. – Bernard Igiri – 2011-09-19T18:18:53.643


The problem with your code is that JavaScript is case sensitive. Your method call


should actually be


Try fixing it and see if that helps:

if (test.indexOf("title") !=-1) {


Posted 2009-11-24T13:04:29.157

Reputation: 8 497

11@JeremyW, I would say at this point the value of this answer is that people that have made this exact same mistake (indexof instead of indexOf) can find this answer and see what's going on. I wouldn't touch the question any more. – Victor – 2014-11-18T13:23:00.333


There is a string.includes in ES6:

> true

Note you may need to load es6-shim or similar to get this working on older browsers.



Posted 2009-11-24T13:04:29.157

Reputation: 12 151

5because I was used to "contains" in other languages and just implemented my feature with it, I just ran into the error. So, short feedback about the support. Firefox 19 - OSX => OK, Firefox 19 - Windows => NOK, Chrome - OSX,Windows => NOK – Patrick Hammer – 2013-02-21T10:18:58.430

4Like this? String.prototype.contains = function (segment) { return this.indexOf(segment) !== -1; }; (BTW: Doing things on the prototype is bad) – Nijikokun – 2013-05-10T02:50:15.193

4It is not support in chrome.....:( – Krunal Patel – 2014-06-24T11:15:40.193

That's lightyears ahead of us. Only an ES7 proposal.

Still - a nice heads up, and I hope the day comes soon when we can safely use it :). – justnorris – 2014-12-05T08:59:19.073

6@Norris It's in ES6. Load ES6 shim. You can use it now. – mikemaccana – 2015-01-15T14:56:51.970

8.contains() and .includes() are both experimental, re: non-standard. I would not recommend their use in production systems. I'd stick with .indexOf() for now. – Mike S. – 2015-03-22T13:47:23.967

1you can use includes() if you are pre-compiling from ES6 to ES5 using babel – steven iseki – 2015-05-25T07:21:15.607

latest chrome supports this method, but IE10 doesn't. Be aware of using it – MarkosyanArtur – 2015-11-11T11:09:30.493

The recommended Polyfill is: `if (!String.prototype.includes) { String.prototype.includes = function(search, start) { 'use strict'; if (typeof start !== 'number') { start = 0; }

if (start + search.length &gt; this.length) {
  return false;
} else {
  return this.indexOf(search, start) !== -1;

}; }`

– Jeremy Odekirk – 2016-06-02T19:17:53.930

Dont use includes it`ll break in IE11. Learn the hard way. – TommyT – 2016-09-09T18:04:30.370

Is there a way to make the function case-insensitive? If not, curious as to which is faster: search() using regex with the case insensitivity modifier or toLowerCase() with includes(). – Mark – 2017-12-15T10:31:40.870


var index = haystack.indexOf(needle);


Posted 2009-11-24T13:04:29.157

Reputation: 15 162


You could use the JavaScript search() method.

Syntax is:

It returns the position of the match, or -1 if no match is found.

See examples there: jsref_search

You don't need a complicated regular expression syntax. If you are not familiar with them a simple"title") will do. If you want your test to be case insensitive, then you should do


Posted 2009-11-24T13:04:29.157

Reputation: 2 465

31I haven't run a benchmark, but would str.toLowerCase().indexOf(searchstr.toLowerCase()) be much more efficient for case-insensitive search? – Tim S. – 2012-01-31T10:29:13.917


With a benchmark and it turns out search is more efficient for case insensitive searching. But it could be tricky to use regex search as you need to escape some characters.

– misaxi – 2013-07-09T06:13:27.640

12This seems like it would be slower than the indexOf function because it would have to parse the RegEx. However, if you want something case insensitive, your way would be the way to go (I think), although that was not what was asked. Even though it wasn't asked, I'm voting this up just because of the case insensitive option. – bgw – 2010-06-03T22:21:33.393

2Search can lead to bugs. As misaxi said, you then have to escape some characters. I was using search not realizing that the parameter expected a regex, and was searching for the pipe character. As it turns out, any string .search('|') == 0. – James Foster – 2014-03-09T10:52:05.440


You can use an escapeRegExp function to make the serach text safe. function escapeRegExp(string){ return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } from

– Mark – 2014-06-05T16:23:08.043

.search() is for regular expressions. For strings it's better to use .indexOf(). – Michał Perłakowski – 2016-01-16T09:18:47.053


String.prototype.includes() was introduced in ES6.

Determines whether one string may be found within another string, returning true or false as appropriate.


var contained = str.includes(searchString [, position]);  



A string to be searched for within this string.


The position in this string at which to begin searching for searchString defaults to 0.


var str = "To be, or not to be, that is the question.";

console.log(str.includes("To be"));    // true
console.log(str.includes("question")); // true
console.log(str.includes("To be", 1)); // false  


This may require ES6 shim in older browsers.

Aniket Kulkarni

Posted 2009-11-24T13:04:29.157

Reputation: 10 568


FWIW the linked MDN page has a simple shim/polyfill:

– Salman Abbas – 2016-09-13T19:39:11.903


If you were looking for an alternative to write the ugly -1 check, you prepend a ~ tilde instead.

if (~haystack.indexOf('needle')) alert('found');

Joe Zimmerman - you'll see that using ~ on -1 converts it to 0. The number 0 is a falsey value, meaning that it will evaluate to false when converted to a Boolean. That might not seem like a big insight at first, but remember functions like indexOf will return -1 when the query is not found. This means that instead of writing something similar to this:

if (someStr.indexOf("a") >= 0) {
  // Found it
} else  {
  // Not Found

You can now have fewer characters in your code so you can write it like this:

if (~someStr.indexOf("a")) {
  // Found it
} else  {
  // Not Found

More details here

Christian Landgren

Posted 2009-11-24T13:04:29.157

Reputation: 7 979


Yes, now I would rather recommend polyfill the ES6 standard includes() by following this:

– Christian Landgren – 2016-10-10T09:32:01.537


This piece of code should work well:

var str="This is testing for javascript search !!!";
if("for") != -1) {


Posted 2009-11-24T13:04:29.157

Reputation: 989

it searches for the passed character or a word if it is found then search returns a integer value which is the position of word in the entire string. If a word or a character is not found then it search function returns -1. – vaibhav – 2012-06-01T04:43:03.093


A common way to write a contains method in JavaScript is:

if (!String.prototype.contains) {
    String.prototype.contains = function (arg) {
        return !!~this.indexOf(arg);

The bitwise negation operator (~) is used to turn -1 into 0 (falsey), and all other values will be non-zero (truthy).

The double boolean negation operators are used to cast the number into a boolean.


Posted 2009-11-24T13:04:29.157

Reputation: 128 837

13What's the advantage of !!~ over &gt;-1? – alex – 2012-12-12T04:29:21.483

3@alex, There isn't any particular advantage other than not relying on magic numbers. Use what you feel comfortable with. – zzzzBov – 2012-12-12T04:59:41.910

13@zzzzBov !~~ is just as much relying on the magic number -1, and the fact that its bitwise representation is the complement of 0. – Martijn – 2013-05-14T09:33:25.397

9!!~this.indexOf(arg); isn't easy understandable and not as clear in the context as it must be. It also relays on the fact ~-1 is 0, agreed with @Martijn. Also it's slower than simple comparison with -1. But clearness is the main factor. – babinik – 2013-05-20T15:40:16.077

1@Nick, I never claimed that it was a good way, I just said it was a common way. As far as clarity is concerned, I feel that it's a reasonable way to save a couple bytes for a library, but I tend to use foo.indexOf('bar') &gt; -1 – zzzzBov – 2013-05-20T15:43:56.187

Not to mention some languages (I don't know if JavaScript also does this) can return any value below 0 if not found. They would return the negative of the last searched index. – Stephan Bijzitter – 2015-02-10T11:00:55.297


In ES5

var s = "foo";
alert(s.indexOf("oo") > -1);

In ES6 there are three new methods: includes(), startsWith(), endsWith().

var msg = "Hello world!";

console.log(msg.startsWith("Hello"));       // true
console.log(msg.endsWith("!"));             // true
console.log(msg.includes("o"));             // true

console.log(msg.startsWith("o", 4));        // true
console.log(msg.endsWith("o", 8));          // true
console.log(msg.includes("o", 8));          // false


Posted 2009-11-24T13:04:29.157

Reputation: 3 314


– zloctb – 2016-08-02T03:59:09.943


Instead of using code snippets found here and there on the web, you can also use a well-tested and documented library. Two Options I would recommend:

1st option: Use Lodash: It has an includes method:

_.includes('foobar', 'ob');
// → true

Lodash is the most popular javascript library dependency for npm and has loads of handy javascript utility methods. So for many projects you would want this anyway ;-)

2nd option: Or use Underscore.string: It has an include method:

_.str.include('foobar', 'ob');
// → true

Here is the description of Underscore.string, it just adds 9kb but gives you all the advantages a well-tested and documented library has over copy'n'paste code snippets:

Underscore.string is JavaScript library for comfortable manipulation with strings, extension for Underscore.js inspired by Prototype.js, Right.js, Underscore and beautiful Ruby language.

Underscore.string provides you several useful functions: capitalize, clean, includes, count, escapeHTML, unescapeHTML, insert, splice, startsWith, endsWith, titleize, trim, truncate and so on.

Note well, Underscore.string is influenced by Underscore.js but can be used without it.

Last not Least: With JavaScript version ES6 comes an built-in includes method:

// → true

Most modern browsers already support it, have an eye on the ES6 compatibility table.


Posted 2009-11-24T13:04:29.157

Reputation: 1 593

4I don't see how figuring out the underscore method is in any way superior to simply using the well-documented core functionality provided in javascript, as illustrated here. To the type of coder that copies and pastes code, your sample code would be no more or less a "copy'n'paste code snippet" than any other solution provided here, except, it would require the addition of a library. Adding libraries simply to accomplish tasks that are just as easily done using the native language, regardless of library size, is bad advice. -1 from me for knee-jerk library use on a old question. – Chris Baker – 2014-01-12T05:37:57.327

8If you are using Underscore already, you should probably use this approach anyway, as it makes your code more readable and more self-explanatory to people not that familiar with JavaScript... Remember that Stack Overflow answers are useful for more people than just the OP. – whirlwin – 2015-01-04T22:30:02.570

_.str.include seems to be gone in underscore – pixelearth – 2016-04-24T17:13:26.423

@pixelearth It's not in underscore, but underscore.string. The link under include in the answer points to the description ;) If you use underscore currently, lodash might be a better solution anyway as it comes with its own includes method and even more very useful helper functions. – nachtigall – 2016-04-25T12:56:33.523


You can use jQuery's :contains selector.


Check it here: contains-selector


Posted 2009-11-24T13:04:29.157

Reputation: 1 286

25That searches DOM elements though… – sam – 2013-09-26T21:03:52.237

21dom parsing has nothing to do with the question – oligofren – 2013-11-01T12:06:09.040

4it's loosely related... if the string you're searching through happens to be located within a DOM element, jQuery's :contains selector can be used. – Joshua Burns – 2013-11-20T20:50:51.017


Use a regular expression:



Posted 2009-11-24T13:04:29.157

Reputation: 148 464

71Using a regex is a little overhead to only check for the presence of a substring. – Fabian Vilers – 2009-11-24T13:55:23.173

5Benchmarks show otherwise; regex is more efficient in many cases, and more importantly, flexible enough to handle edge cases in a way that other solutions are not. – Chris Baker – 2014-04-10T21:48:39.530

23Using regex usually results in 2 problems instead of one. – martynas – 2014-04-15T08:48:51.090

7If your string includes . or other regexp literals you will get false positives. – Christian Landgren – 2014-08-29T10:20:19.890

1This solutions breaks unless string is regex-escaped. – Triptych – 2015-10-12T21:22:29.757

indexOf() is made for simple search and is faster than RegEx which is made for more complex searching. Use functions depend on what you want to solve. – step – 2018-08-04T19:08:33.080


Another option of doing this is:

You can use the match function, that is, something like:

x = "teststring";

if (x.match("test")) {
     // Code

match() can also work with regular expression :

x = "teststring";

if (x.match(/test/i)) {
     // Code

David Craig

Posted 2009-11-24T13:04:29.157

Reputation: 140

6if the string "test" includes a . or other regexp literals you will get false positives. – Christian Landgren – 2014-08-29T10:19:37.833

It's always regex. "If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj)", see:

– Dem Pilafian – 2018-11-08T02:55:04.387


You were looking for .indexOfMDN.

indexOf is going to return an index to the matched substring. The index will correlate to where the substring starts. If there is no match, a -1 is returned. Here is a simple demo of that concept:

var str = "Hello World"; // For example, lets search this string,
var term = "World"; // for the term "World",
var index = str.indexOf(term); // and get its index.
if (index != -1) { // If the index is not -1 then the term was matched in the string,
  alert(index); // and we can do some work based on that logic. (6 is alerted)

Travis J

Posted 2009-11-24T13:04:29.157

Reputation: 63 379


You need to call indexOf with a capital "O" as mentioned. It should also be noted, that in JavaScript class is a reserved word, you need to use className to get this data attribute. The reason it's probably failing is because it's returning a null value. You can do the following to get your class value...

var test = elm.getAttribute("className");
var test = elm.className


Posted 2009-11-24T13:04:29.157

Reputation: 1 209

4Your first approach is not correct:

elm.getAttribute("class") == elm.className != elm.getAttribute("className")
 – Sebastian vom Meer  – 2013-03-12T14:22:50.510


This just worked for me. It selects for strings that do not contain the term "Deleted:"

if (eventString.indexOf("Deleted:") == -1)


Posted 2009-11-24T13:04:29.157

Reputation: 535


Since the question is pretty popular, I thought I could add a little modern flavor to the code.

// const           : creates an immutable constant
const allLinks   = document.getElementsByTagName("a");
// []  : gives access to the reduce method on a HTMLCollection
// () => {}        : ES6 arrow function
const foundLinks = [], (sum, link) => {
     // bitwise OR : converts the boolean value to a number
     return sum + (link.classList.contains("title") | 0);
}, 0);

// template literal
console.log(`Found ${foundLinks || "no"} title class`);

BTW, the correct answer is misspelling indexOf or the non-standard String.contains. Loading an external library (especially if the code is written in pure JavaScript) or messing with String.prototype or using a regular expression is a little overkill.

Jay Harris

Posted 2009-11-24T13:04:29.157

Reputation: 3 630


There is a sleek and better way to do this and it is using the (BitWise NOT) operator.

if(~"John".indexOf("J")) {
else {
  alert("Not Found");

The Bitwise Not converts "x" into -(x + 1) so, if the x turns out -1 from indexOf method.then it will be converted into -( -1 + 1) = -0 which is a falsy value .


Posted 2009-11-24T13:04:29.157

Reputation: 2 701

1 and predate this answer, consider deleting it in favor of the later community wiki answer. – zzzzBov – 2016-05-02T20:28:09.347


String.prototype.indexOf() or!

As others have already mentioned, JavaScript strings have both an indexOf and search method.

The key difference between both, is that indexOf is for plain substrings only, whereas search also supports regular expressions. Of course, an upside of using indexOf is that it's faster.

See also In JavaScript, what is the difference between indexOf() and search()?.

Implementing your own String.prototype.contains() method

If you want to add your own contains method to every string, the best way to do it would be @zzzzBov's approach:

if (!String.prototype.contains) {
    String.prototype.contains = function (arg) {
        return !!~this.indexOf(arg);

You would use it like this:

'Hello World'.contains('orl');

Implementing a custom utility library

It is generally frowned upon to add your own custom methods to standard objects in JavaScript, for example, because it might break forward compatibility.

If you really want your own contains method and/or other custom string methods, it's better to create your own utility library and add your custom string methods to that library:

var helper = {};

helper.string = {
    contains : function (haystack, needle) {
        return !!~haystack.indexOf(needle);

You would use it like this:

helper.string.contains('Hello World', 'orl');

Using a third-party utility library

If you don't want to create your own custom helper library, there is - of course - always the option of using a third-party utility library. As mentioned by @nachtigall, the most popular ones are Lodash and Underscore.js.

In Lodash, you could use _.includes(), which you use like this:

_.includes('Hello World', 'orl');

In Underscore.js, you could use _.str.include(), which you use like this :

_.str.include('Hello World', 'orl');

John Slegers

Posted 2009-11-24T13:04:29.157

Reputation: 27 166



var a  = "Test String";

} else {
     //not found 

Ali Abbas

Posted 2009-11-24T13:04:29.157

Reputation: 159



Posted 2009-11-24T13:04:29.157


@MikeMüller The question was why there is not a String.contains method, and the answer is that there is one in ES6. The link is provided merely as additional documentation. – None – 2016-01-04T05:35:14.077

There was a contains in pre-release ES6 but it was changed to includes. Your contains method link redirects to the includes method here: Here's the proof it was renamed:

– Jeremy Odekirk – 2016-06-02T19:08:24.057


Simple workaround

if (!String.prototype.contains) {
  String.prototype.contains= function() {
    return String.prototype.indexOf.apply(this, arguments) !== -1;

you can use in the following way

"hello".contains("he") // true
"hello world".contains("lo w")//true
"hello world".contains("lo wa")//false
"hello world".contains(" ")//true
"hello world".contains("  ")//false

MDN reference

Sriramajeyam Sugumaran

Posted 2009-11-24T13:04:29.157

Reputation: 395

1Don’t modify objects you don’t own. – Michał Perłakowski – 2015-12-11T18:25:47.357


JavaScript code to use the contains method in an array:

        <h2>Use of contains() method</h2>
            Array.prototype.contains = function (element) {
                for (var i = 0; i < this.length; i++) {
                    if (this[i] == element) {
                        return true;
                return false;
            arr1 = ["Rose", "India", "Technologies"];
            document.write("The condition is "+arr1.contains("India")+"<br>");

    <b>[If the specified element is present in the array, it returns true otherwise
    returns false.]</b>


In the given code the contains method determines whether the specified element is present in the array or not. If the specified element is present in the array, it returns true, otherwise it returns false.

Tarun Gupta

Posted 2009-11-24T13:04:29.157

Reputation: 4 944

3-1; this question is about strings, not arrays. – Mark Amery – 2014-04-20T16:49:42.840

3a string is an array of chars :) – daslicht – 2014-04-22T08:51:35.887

1The sample HTML is not well formed - the body tag is missing. – Peter Mortensen – 2014-10-26T10:22:03.207


To collect some kind of valid solutions:

var stringVariable = "some text";
var findString = "text";

//using `indexOf()`
var containResult1 = stringVariable.indexOf(findString) != -1;
document.write(containResult1+', ');

//using `lastIndexOf()`
var containResult2 = stringVariable.lastIndexOf(findString) != -1;
document.write(containResult2+', ');

//using `search()`
var containResult3 = != -1;
document.write(containResult3+', ');
//using `split()`
var containResult4 = stringVariable.split(findString)[0] != stringVariable;


Posted 2009-11-24T13:04:29.157

Reputation: 12 785

I don't see any point in using lastIndexOf if you only want to check if a string contains a substring. search method is only for regular expressions. split method makes it only more complicated. – Michał Perłakowski – 2015-12-11T18:29:40.207


Since there is a complaint about using the prototype, and since using indexOf makes your code less readable, and since regexp is overkill:

function stringContains(inputString, stringToFind) {
    return (inputString.indexOf(stringToFind) != -1);

That is the compromise I ended up going for.


Posted 2009-11-24T13:04:29.157

Reputation: 1 822



 var str = "My big string contain apples and oranges";
 var n = str.indexOf("apples"); 
 alert(n); //will alert 22, -1 if not found


  <p>My big string contain apples and oranges</p>
  alert($("p:contains(apples)")[0] != undefined); //will alert true if found

Alain Gauthier

Posted 2009-11-24T13:04:29.157

Reputation: 382


In ES6, we have something calls includes which does exactly what you want: So you can simply do like this:


Also in ES5, if you widely use it, you can simply add it like this:

String.prototype.includes = String.prototype.includes || function(str) {
  return this.indexOf(str) > -1;


Posted 2009-11-24T13:04:29.157

Reputation: 43 514


Use the inbuilt and simplest one i.e match() on the string. To achieve what you are looking forward do this:

var stringData ="anyString Data";

var subStringToSearch = "any";

// This will give back the substring if matches and if not returns null
var doesContains = stringData.match(subStringToSearch);

if(doesContains !=null) {
    alert("Contains Substring");

Ankur Madaan

Posted 2009-11-24T13:04:29.157

Reputation: 11


The easyest way is indeed using indexOf. To just check a string string for a substring substr you can use this method:

string = "asdf";
substr = "as";
alert(string.indexOf(substr) == -1 ? false : true);

As you wanted the function string.contains(), you can implement it yourself like this:

String.prototype.contains = function(test) {
    return this.indexOf(test) == -1 ? false : true;

Now you can use this ecen shorter method to check if a string contains a special substring:

string = "asdf";

Here is a JSFiddle as well.


Posted 2009-11-24T13:04:29.157

Reputation: 1 084


Simple answer, works 100%

if (!String.prototype.contains) {
  String.prototype.contains= function() {
    return String.prototype.indexOf.apply(this, arguments) !== -1;

some examples

"hello".contains("he") // true
"hello world".contains("lo w")//true
"hello world".contains("lo wa")//false
"hello world".contains(" ")//true
"hello world".contains("  ")//false

Kamil Ibadov

Posted 2009-11-24T13:04:29.157

Reputation: 1 332


If you don't like the !!~, etc. tricks, you can simply add +1 to the result of .indexOf(). This way if a string is not found, -1 + 1 = 0 will be falsy, 0.. + 1 = 1.. will be truthy:

if ("StackOverflow".indexOf("Stack") + 1 )
    alert('does not contain');


Posted 2009-11-24T13:04:29.157

Reputation: 12 248

1Yeah I don't like those obtuse tricks either and was going to write the following up as an answer but yours is close enough so will merely comment with my variation: ++'foo'.indexOf('bar') – George Jempty – 2017-12-03T00:01:58.653

@GeorgeJempty: Your variation is a nice idea, but my Firefox throws errors, no matter ho much I twist it. :( – biziclop – 2017-12-03T17:54:58.123

Yeah as it turns out apparently you need to assign the result of indexOf to a variable first, see how I did it in this question:

– George Jempty – 2017-12-03T18:51:38.497


One more function, search:

var str = "Stack Overflow";
var n ="Overflow");
if (n != -1)
    alert('String exists')

Mahendra Jella

Posted 2009-11-24T13:04:29.157

Reputation: 3 190

2search is for regular expressions – Michał Perłakowski – 2015-12-11T18:30:49.240


Try this:

if ('Hello, World!'.indexOf('orl') !== -1)
    alert("The string 'Hello World' contains the substring 'orl'!");
    alert("The string 'Hello World' does not contain the substring 'orl'!");

Here is an example: jsfiddle

Oliver Ni

Posted 2009-11-24T13:04:29.157

Reputation: 1 381


This is a function to check if a substring is existing in a string or not:

function isStringMatch(str, str_to_match) {
    return (str.indexOf(str_to_match) > -1);

Satish Sharma

Posted 2009-11-24T13:04:29.157

Reputation: 8 327

3Just a heads up... this should be either &gt;=0, &gt;-1, or (my preference) !== -1, as this will fail in its current form if the string begins with the substring. – Karl White – 2014-02-01T08:07:36.210


There are multiple ways to do this. The most frequently used would be the indexOf() method. indexOf() returns the position of the string passed to it as argument and -1 if the string doesn't contain the passed string.

let str = "A cat and a dog";
str.indexOf("cat"); // returns 2
str.indexOf("panda"); // returns -1

Devashish Jaiswal

Posted 2009-11-24T13:04:29.157

Reputation: 550


I know that best way is str.indexOf(s) !== -1;

I suggest another way(str.replace(s1, "") !== str):

var str = "Hello World!", s1 = "ello", s2 = "elloo";
alert(str.replace(s1, "") !== str);
alert(str.replace(s2, "") !== str);

Sherali Turdiyev

Posted 2009-11-24T13:04:29.157

Reputation: 1 303


You can use indexOf which returns the position of the string. If not found, it will return -1. So if the method returns -1 string doesn't exist

var string = "This is a test string",
substring = "test";
if(string.indexOf(substring) >= 0)
  //substring exist
  //substring does not exist


Posted 2009-11-24T13:04:29.157



With ECMAScript 2015, we can use includes()

let s = "foo";

Raman Sahasi

Posted 2009-11-24T13:04:29.157

Reputation: 15 408


You can also do something like this

var snipers = " Vasily Zaytsev, Simo Hayha, Chris Kyle";
var me = "Josip";

function printSniperStatus (person) {
    if (aContainsB(snipers, person)) {
        console.log(person + " is a sniper.");
    } else {
        console.log(person + " is NOT a sniper.");

// Outputs: "Josip is NOT a sniper."

Josip Ivic

Posted 2009-11-24T13:04:29.157

Reputation: 2 889


Very simple:

var a = "foo", b= "oo";
if (a.indexOf(substring) !== -1) {
    // has

Behnam Mohammadi

Posted 2009-11-24T13:04:29.157

Reputation: 6 724


Yet another answer...

Usually, I would expect a String.contains() method,...

Depending on what usually mean, there is at least one way not already presented on all previous answer.

This could be usefull on very specific cases, but:

var mystring="Foo bar baz"
var searchstr="bar"
var arraysplt=mystring.split(searchstr)
var containbool=typeof(arraysplt[1])=="string";

If searchstr is present at least once, even at end of mystring, then typeof(split(...)[1]) is string (an empty string). If not present, then typeof(split(...)[1]) become undefined.


typeof( mystring.split( searchstr )[1] ) == "string";

But using this method could only be usefull only if arraysplt's elements will be usefull lather in the script.

... so this shorted method seem completely useless (I think)...

But, if your goal is to split a string, using indexOf to ensure presence of separator is useless.

F. Hauri

Posted 2009-11-24T13:04:29.157

Reputation: 34 757


I'm surprised no one has mentioned KMP here. What is KMP? KMP algorithm provides worst-case linear time substring search, so it is a reasonable way if you do care about worst-case time complexity. Link to JavaScript KMP implementation sample


Posted 2009-11-24T13:04:29.157

Reputation: 868


Using Indexof that can be identified easily, Example:

var array = [2, 9, 9];
array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0

The result is in comment after the line

سیدرسول میرعظیمی

Posted 2009-11-24T13:04:29.157

Reputation: 229


var string = "foo",
    substring = "oo";
console.log(string.indexOf(substring) !== -1);


Posted 2009-11-24T13:04:29.157

Reputation: 542


The indexOf method is the best solution as it is supported by all the browsers

The syntax is : string.indexOf(searchvalue, start)

where start is an optional parameter.


Posted 2009-11-24T13:04:29.157

Reputation: 65


result = 'GBP|1800';
//if pipe delimeter is there it returns true else false.
    console.log('go default:' +result);
    var cur = result.substring(0, 3);//returns GBP
    console.log('go default cur:' +cur);
    var minmum_fee = result.substring(4);//gets the substring amount
    console.log('go default minmum_fee:' +minmum_fee);

    console.log('not found:' +result);


Posted 2009-11-24T13:04:29.157

Reputation: 2 248