https://www.baseclass.io/guides/string-handling-modern-js :BaseClass The complete guide to Working With Strings in Modern JavaScript This guide is intended to cover everything you need to know about creating, manipulating and comparing strings in JavaScript. extra tips and common issues sections along the way will hopefully teach you something new, and help you to avoid common mistakes. If I've missed anything, please let me know and I'll add it! Remember to bookmark this page to refer to later! Contents * Get more like this Creating strings There are fundamentally two categories of strings in JavaScript; string primitives and String objects. Primitives String primitives are created like this: let example1 = "BaseClass" // or let example2 = String("BaseClass") In almost all cases, you should use one of these methods to create a new string. Objects You can create a String object using the new keyword. The only real advantage that an object has over a string primitive is that you can attach additional properties to it: let website = new String("BaseClass") website.rating = "great!" There are very few cases where this is useful though. In almost all cases, you should create a string primitive. All of the string methods you are familiar with are part of the String object, not the primitive. When you call a method on a string primitive, JavaScript 'auto-boxes', or wraps, the primitive in a String object, and calls the method on that object instead. Combining strings You can combine (or 'concatenate') multiple strings to create a new one using the + symbol: let name = "Base" + "Class" // Output: "BaseClass" This can also be used to split string creation over multiple lines for readability: let name = "This really is " + "a very " + "long string" // "This really is a very long string" You can also concatenate strings with variables (non-string variables will be converted to strings): let precinct = 99 let name = "Brooklyn " + precinct // Output: "Brooklyn 99" To create a new string by adding to the end of an existing one, use + =: let name = "Three " name += "Blind " name += "Mice" // "Three Blind Mice" You can also concatenate strings and variables using the string.concat() method, but that is not recommended for performance reasons. Instead, use the + or += operators above Repeating a string The repeat() method returns a new string, which contains the original string repeated a number of times: let warning = "Londons Burning. " let result = warning.repeat(2) // "London's Burning. London's Burning. " You can use this in the following browsers: string.repeat() * Chrome 41+ * Edge 12+ * Firefox 24+ * Safari 9+ * Opera 28+ Template Literals Template Literals allow you to combine variables and text into a new string using a more readable syntax. Instead of double or single-quotes, enclose the string in back-ticks. Then, reference variables within the string using ${variableName}. Before let opinion = "Love" let tweet = "I " + opinion + " JavaScript" // "I Love JavaScript" After let opinion = "Love" let tweet = `I ${opinion} JavaScript` // "I Love JavaScript" Brower support for Template Literals is now very good: Template Literals * Chrome 41+ * Edge 13+ * Firefox 34+ * Safari 9.1+ * Opera 29+ Comparing strings Equality When you know you are comparing two string primitives, you can use either the == or === operators: "abba" === "abba" // true "abba" == "abba" // true If you are comparing a string primitive to something that is not a string, == and === behave differently. When using the == operator, the non-string will be coerced to a string. That means that JavaScript will try and make it a string before comparing the values. 9 == "9" // becomes "9" == "9" //true For a strict comparison, where non-strings are not coerced to strings, use ===: 9 === "9" // false The same is true of the not-equal operators, != and !==: 9 != "9" // false 9 !== "9" // true If you're not sure what to use, prefer strict equality using ===. When using String objects, two objects with the same value are not considered equal: new String("js") == new String("js") // false new String("js") === new String("js") // false Case sensitivity When a case-insensitive comparison is required, it is common to convert both strings to upper or lowercase and compare the result. "Hello".toUpperCase() === "HeLLo".toUpperCase() // true Sometimes you need more control over the comparison, though. See the next section for that.. Handling diacritics Diacritics are modifications to a letter, such as e or z. You may wish to specify how these are handled when comparing two strings. For example, in some languages it is common practice to exclude accents from letters when writing in uppercase. If you need a case-insensitive comparison, simply converting two strings to the same case first using toUpperCase() or toLowerCase() would not account for this addition/removal of accents, and might not give you the result you are expecting. When you need more fine-grained control of the comparison, use localeCompare instead: let a = 'Resume'; let b = 'RESUME'; // Returns 'false' - the strings do not match a.toLowerCase() === b.toLowerCase() // Returns '0' - the strings match a.localeCompare(b, undefined, { sensitivity: 'base' }) The localeCompare method allows you to specify the 'sensitivity' of the comparison. Here we used a 'sensitivity' of base to compare the strings using their 'base' characters (meaning it will ignore case and accents). This is supported in the following browsers: localeCompare() * Chrome 24+ * Edge 12+ * Firefox 29+ * Safari 10+ * Opera 15+ Greater/less than When comparing strings using the < and > operators, JavaScript will compare each character in 'lexicographical order'. That means that they are compared letter by letter, in the order they would appear in a dictionary: "aardvark" < "animal" // true "gamma" > "zulu" // false When comparing strings using < or >, lowercase letters are considered larger than uppercase. "aardvark" > "Animal" // true This is because JavaScript is actually using each character's value in Unicode, where lowercase letters are after uppercase letters. True or false strings Empty strings in JavaScript are considered false when compared with the == operator (but not when using ===) ("" == false) // true ("" === false) // false Strings with a value are 'true', so you can do things like this: if (someString) { // string has a value } else { // string is empty or undefined } Multi-line strings You can add new lines in a string using \n: let result = "The winner is:\nBaseClass!" // The winner is: // BaseClass! In a Template Literal, new lines are respected within the backticks: let result = `The winner is: BaseClass!` // The winner is: // BaseClass! In Template Literals, you can escape line-breaks by adding a \ at the end of the line. let result = `All on \ one line` // "All on one line" Padding strings You can add whitespace to the start or end of a string until it reaches a specified length using padStart() or padEnd(): // Pad the string "hello" with whitespace to make // it 8 characters long: "hello".padStart(8) // " hello" "hello".padEnd(8) // "hello " Instead of whitespace, you can pad the target string with another string, by passing it as the second parameter. That string will be repeated until the target length is reached (the string will be truncated if it does not fit evenly into the required padding): // Pad "Train" to 13 characters using the string "Choo" "Train".padStart(13, "Choo") // Output: "ChooChooTrain" This is supported by all modern browsers: string.padStart() string.padEnd() * Chrome 57+ * Edge 15+ * Firefox 48+ * Safari 10+ * Opera 44+ Splitting a string You can split a string in to an array using the split() method. Common use cases for this are: Turning a sentence into an array of words, by splitting it on spaces: "Welcome to Paradise".split(" ") // [ "Welcome", "to", "Paradise" ] .. or splitting a multi-line string into individual lines: let song = `Hello, Is it me you're looking for?` song.split("\n") // [ "Hello,", "Is it me you're looking for?" ] You can also limit the number of items you would like back from split (), by passing an optional second parameter: // Get only the first two words "The quick brown fox".split(" ", 2) // Output: [ "The", "quick" ] If you need to turn a string in to an array of characters, the split () method does not work well for Unicode characters that are represented by 'surrogate pairs': "!".split("") // ["", "", "!"] In modern browsers, you can use the spread operator instead: [..."!"] // ["", "!"] Extracting part of a String Substrings These methods take the index of the first character you wish to extract from the string. They return everything from that character to the end of the string: "I am Groot!".slice(5) // "Groot!" "I am Groot!".substring(5) // Groot! The second (optional) argument is the character at which you'd like to stop. This final character is not included in the output: // Extract a new string from the 5th character, // up to (but not including!) the 10th character "I am Groot!".slice(5, 10) // "Groot" "I am Groot!".substring(5, 10) // "Groot" So, which one should you use? They are very similar, but with some subtle differences: * If the end value is higher than the start value, substring() will 'correct' them by swapping them, but slice() will just return an empty string. * substring() treats a negative index as 0. With slice(), you can use a negative number to count backwards from the end of the string. For example, .slice(-3) will return the last 3 characters of the string. There is also a substr() method, that is similar to slice() and substring(). This is a legacy API. While it is unlikely to be used soon, you should use one of the two methods above instead where possible. Single characters The charAt() method returns a specific character from the string (remember, indexes are 0-based): "Hello".charAt(1) // "e" You can return the UTF-16 code for a character in a string using charCodeAt(): "Hello".charCodeAt(1) // 101 You can also treat a string as an array, and access it directly like this: "Hello" [1] // e Accessing a string as an array could lead to confusion when the string is stored in a variable. Using charAt() is more explicit: // What is 'someVariable'? let result = someVariable[1] // 'someVariable' is clearly a string let result = someVariable.charAt(1) Changing the case of a string You can make a string all-caps like this: "hello".toUpperCase() // "HELLO Or all lowercase like this: "Hello".toLowerCase() // "hello These methods are commonly used to convert two strings to upper/ lowercase in order to perform a case-insensitive comparison of them. Depending on the strings you are comparing, you might want more control over the comparison. Consider using localeCompare instead. See this section. Removing whitespace The following methods will remove all spaces, tabs, non-breaking spaces and line ending characters (e.g. \n) from relevant part the string: " Trim Me ".trim() // "Trim Me" " Trim Me ".trimStart() // "Trim Me " " Trim Me ".trimEnd() // " Trim Me" "With Newline\n".trimEnd() // "With NewLine" trimStart() and trimEnd() were introduced in ES10, and are now the 'preferred' methods to use according to that specification. At the time of writing, however, these are not supported in the Edge browser. For compatibility in all modern browsers, use trimLeft() and trimRight(): " Trim Me ".trimLeft() // "Trim Me " " Trim Me ".trimRight() // " Trim Me" Searching for text in a string Find the position of a substring You can search for a string within another string using indexOf(). This will return the position of first occurrence of the search term within the string, or -1 if the string is not found: "Superman".indexOf("man") // '5' "Superman".indexOf("foo") // '-1' You can also use the regular expression method search() to do the same thing: "Superman".search("man") // '5' To search for the last occurrence of a search term, use lastIndexOf (): "Yabba Dabba Doo".indexOf("bb") // '2' "Yabba Dabba Doo".lastIndexOf("bb") // '8' All of these methods will return -1 if the search term is not found in the target string. Starts/Ends with You can use the indexOf() methods above to check whether a string begins with, or ends with, a search term. However, ES6 added specific methods for this: "Wonder Woman".startsWith("Wonder") // true "Wonder Woman".endsWith("Woman") // true string.startsWith() string.endsWith() * Chrome 41+ * Edge 12+ * Firefox 17+ * Safari 9+ * Opera 28+ Includes If you don't care about the specific position of the substring, and only care whether it is in the target string at all, you can use includes(): "War Games".includes("Game") // true string.includes() * Chrome 41+ * Edge 12+ * Firefox 40+ * Safari 9+ * Opera 28+ Regular Expressions To find the first occurrence of a regular expression match, use .search(). // Find the position first lowercase character "Ironman 3".search(/[a-z]/) // '1' To return an array containing all matches of a regular expression, use match(), with the /g (global) modifier: // Return all uppercase letters "This is England".match(/[A-Z]/g) // Output: [ "T", "E" ] (using match() without the /g modifier will return only the first match, and some additional properties such as the index of the result in the original string, and any named capturing groups) If you need more details about each match, including their index in the original string, you can use matchAll. This method returns an iterator, so you can use a for...of loop over the results. You must use a regular expression with the /g/ modifier with matchAll(): // Find all uppercase letters in the input let input = "This is England" let matches = input.matchAll(/[A-Z]/g) // Turn the result into an array, using // the spread operator [...matches] // Returns: // [ // ["T", index: 0, groups: undefined] // ["E", index: 8, groups: undefined] // ] Replacing characters in a string You can use replace() to replace certain text in a string. The first argument to replace() is the text to find and replace, the second is the text to replace it with. Passing a string as the first argument replaces only the first instance of the term: "no no no!".replace("no", "yes") // "yes no no!" If you want to replace all instances of the text, you can pass a regular expression with the 'greedy' modifier (/g) as the first argument: "no no no!".replace(/no/g, "yes") // "yes yes yes!" ES2021 added replaceAll(), to make replacing all instances of a term easier: "no no no!".replaceAll("no", "yes") // "yes yes yes!" You can use this if you only need to support very recent browsers: string.replaceAll() * Chrome 85+ * Edge 85+ * Firefox 77+ * Safari 13.1+ * Opera 71+ Do you want more like this? I'll let you know when I'm working on new lessons and courses, and you'll get early access to anything I do. [ ]Subscribe