Just Enough Text

Understanding JavaScript Strings

In JavaScript, the type used to represent text is called a string. Technically speaking, a string is an unchangeable, ordered sequence of 16-bit values, each typically representing a Unicode character. If that sounds a bit overwhelming, don’t worry—think of it as a fixed list of characters that you can’t directly change. Simple enough, right? For now, let's just call these 16-bit values "characters," as it’s easier to wrap your head around.

String Length and Indexing

The length of a string is simply the number of characters it holds. JavaScript uses zero-based indexing, which just means that the first character is at position 0, the second is at position 1, and so on. Also, unlike some other languages, JavaScript doesn’t have a special type for a single character. So if you want to work with just one character, you can use a string that’s only one character long.

// Define a string
let str = "Hello, world!";

// Get the length of the string
let length = str.length;
console.log(length); // Output: 13 (number of characters in the string)

// Access characters using zero-based indexing
console.log(str[0]); // Output: "H" (first character)
console.log(str[7]); // Output: "w" (eighth character)

// Example of working with a single character as a string
let singleChar = "A"; // A string with one character
console.log(singleChar); // Output: "A"

// Length of a single character string
console.log(singleChar.length); // Output: 1

UTF-16 Encoding and Surrogate Pairs

JavaScript strings use a system called UTF-16 to store characters. Most characters fit into a single unit, so they take up one spot in a string. But some special characters need more space and use two units together, called a 'surrogate pair.' This means that even if a string looks like it has two characters, it might actually just represent one character.

// Define a string with both single and surrogate pair characters
let str = "hello 🌍";

// Length of the string (number of UTF-16 units)
console.log(str.length); // Output: 7 (5 for "hello" + 2 for the surrogate pair "🌍")

// Access characters using zero-based indexing
console.log(str[0]); // Output: "h"
console.log(str[5]); // Output: " "

// Access the surrogate pair characters
// The emoji "🌍" is represented by a surrogate pair
console.log(str[5] + str[6]); // Output: " 🌍"

// Access surrogate pair as a single character
// Convert to array of code units
let codeUnits = Array.from(str);
console.log(codeUnits[5] + codeUnits[6]); // Output: "🌍"

// Length of the surrogate pair in terms of code units
console.log(codeUnits.length); // Output: 7

Including Strings in JavaScript

To include a string in a JavaScript program, all you need to do is wrap the text in a pair of single quotes (' '), double quotes (" "), or backticks. Each option works a bit differently, but the idea is the same—just choose the one that suits your needs. For example, if you’re using single quotes to delimit your string, you can still include double quotes or backticks inside that string without any trouble, and vice versa.

// Single quotes
let single = 'Single quoted string with "double" quotes and `backticks`.';
console.log(single);

// Double quotes
let double = "Double quoted string with 'single' quotes and `backticks`.";
console.log(double);

// Backticks (Template literals)
let backticks = `Backticks allow 'single' and "double" quotes, and support
multiline strings.`;
console.log(backticks);

Multi-Line Strings

Originally, string literals could only be written on a single line, so you might see older code that creates long strings by stitching together shorter ones using the + operator. But, with ES5, you can break a string across multiple lines by ending each line (except the last) with a backslash. If you need to include a newline character in a single-quoted or double-quoted string, you can do so with \n. Backticks, however, let you break stringsacross multiple lines more naturally, with the line breaks becoming part of thestring itself.

// Older method: Concatenating strings with '+'
let oldStyle =
  "This is a very long string " +
  "that is broken into multiple lines " +
  "using the + operator.";
console.log(oldStyle);

// ES5 method: Using backslashes for multi-line strings
let es5Style =
  "This is a long string that spans \
multiple lines using backslashes.";
console.log(es5Style);

// Newline character in single or double-quoted strings
let withNewline = "This string\ncontains a newline.";
console.log(withNewline);

// Modern method: Using backticks (template literals) for multi-line strings
let modernStyle = `This string spans
multiple lines and includes
line breaks directly.`;
console.log(modernStyle);

Using the Backslash for Escaping Characters

In JavaScript, the backslash character plays a special role in strings. It acts as an "escape" mechanism, letting you include characters in a string that would otherwise be tricky to represent. For example, if you need to include a single quote (') inside a string that’s already wrapped in single quotes, you can use the backslash to escape it, like so: 'don't'. Here, the backslash tells JavaScript, "Hey, don’t treat this apostrophe as the end of the string; just include it as a character."

// Escaping single quotes within single-quoted strings
let singleQuoteEscaped = "Don't worry about the single quote.";
console.log(singleQuoteEscaped); // Output: Don't worry about the single quote.

// Escaping double quotes within double-quoted strings
let doubleQuoteEscaped = 'He said, "Hello, World!"';
console.log(doubleQuoteEscaped); // Output: He said, "Hello, World!"

// Escaping backslashes
let backslashEscaped = "Use a double backslash to include a backslash: \\";
console.log(backslashEscaped); // Output: Use a double backslash to include a backslash: \\

Common Escape Sequences

Escape sequences allow you to include special characters that have specific meanings in JavaScript, and they follow a similar pattern. Here’s a quick reference table of common escape sequences and the characters they represent:

Escape SequenceCharacter Represented
'Single Quote (')
"Double Quote (")
\Backslash ()
\nNewline
\tTab
\rCarriage Return
\bBackspace
\fForm Feed
\vVertical Tab
\0Null Character

Don’t worry about trying to memorize all these sequences. Just keep this table handy or bookmark it in your notes so you can easily refer back to it whenever you need to include a special character in your strings. We will provide a link to this table just in case you want to do just that.

Working with Strings

JavaScript makes working with strings a breeze, especially when it comes to tasks like joining or comparing them. One of the most straightforward features is string concatenation, where the + operator comes in handy. Normally, this operator adds numbers, but when used with strings, it combines them. For example, if you have 'Hello, ' and 'world!', using 'Hello, ' + 'world!' will give you 'Hello, world!'.

Comparing strings is just as easy. You can use the === equality operator to check if two strings are exactly the same, or the !=== inequality operator to see if they’re different.

To find out how many characters are in a string, JavaScript offers the length property. For example, 'Hello'.length returns 5, showing you the number of characters in the string.

JavaScript also has a rich set of built-in methods for manipulating strings. Here’s a table of some of the most useful string methods:

MethodDescription
.charAt(index)Returns the character at the specified index.
.charCodeAt(index)Returns the Unicode of the character at the specified index.
.concat(str)Combines the text of two strings and returns a new string.
.includes(str)Checks if one string contains another.
.indexOf(str)Returns the index of the first occurrence of a specified value in a string.
.lastIndexOf(str)Returns the index of the last occurrence of a specified value in a string.string.
.concat(str)Combines the text of two strings and returns a new string.
.slice(start, end)Extracts a section of a string and returns it as a new string.
.substring(start, end)Similar to .slice(), but doesn’t accept negative indices.
.split(separator)Splits a string into an array of substrings based on a separator.
.replace(old, new)Replaces occurrences of a substring with a new substring.
.replaceAll(old, new)Replaces all occurrences of a substring with a new substring.
.toLowerCase()Converts the entire string to lowercase letters.
.toUpperCase()Converts the entire string to uppercase letters.
.trim()Removes whitespace from both ends of a string.
.trimStart()Removes whitespace only from the start of a string.
.trimEnd()Removes whitespace only from the end of a string.
.startsWith(str)Checks if a string starts with a specified value.
.endsWith(str)Checks if a string ends with a specified value.
.match(regex)Searches a string for a match against a regular expression.
.search(regex)Searches a string for a specified value using a regular expression and returns the position.
.repeat(count)Returns a new string with a specified number of copies of the original string.

JavaScript offers a vast array of string methods, and trying to memorize all of them can be overwhelming. Instead of stressing over the details, focus on knowing that these methods exist. When you encounter a problem with strings, refer back to the table you’ve bookmarked or saved to find potential solutions. If you’re ever unsure, don’t hesitate to ask for help. You can even ask ChatGPT, for example, you might say, “Hey ChatGPT, I’m dealing with problem X—are there any JavaScript string methods that could help me with this?” This way, you can leverage the available resources to find the best solution without having to remember every single method.

Immutability of Strings

In the beginning we mentioned that strings are immutable. This means that methods like replace() or toUpperCase() will return a new string without altering the original one. For example, calling 'hello'.toUpperCase() returns 'HELLO', but 'hello' stays the same. You don’t need to worry too much about this right now, but it’s a concept that will become more important as you continue learning.

Template Literals

Starting with ES6, JavaScript introduced a new way to handle strings called template literals, which are enclosed in backticks. The real magic of template literals is their ability to embed JavaScript expressions directly within the string. When you use template literals, any expression inside ${} is evaluated and then converted into a string, which is seamlessly integrated with the rest of your text.

For example, let’s say you want to create a greeting message that includes a person's name and their age. Instead of concatenating strings and variables manually, you can use a template literal like this:

const name = "Alice";
const age = 30;
const message = `Hello, ${name}! You are ${age} years old.`;

console.log(message); // Outputs: Hello, Alice! You are 30 years old.

In this example, ${name} and ${age} are placeholders where the expressions are evaluated and inserted into the string. Everything outside these ${} placeholders is treated as plain text.

Template literals are incredibly versatile—they can span multiple lines without needing special escape characters. This means you can write longer strings that include line breaks and still keep your code clean and readable. For instance:

const multiLineString = `
This is a string
that spans multiple
lines without needing
any special escaping.
`;

console.log(multiLineString); /* Outputs: This is a string
that spans multiple
lines without needing
any special escaping. */

With template literals, you get a more powerful and flexible way to handle strings in JavaScript, making your code more expressive and easier to manage.

Just a quick note

Even though you're progressing through the blue belt series, it’s important to remember that this level isn't necessarily the easiest. At the start, we're laying down a solid foundation, and that can feel a bit overwhelming. Grasping core concepts right from the get-go is a big ask, and it's perfectly okay if you don't have everything like immutability, escape sequences, or UTF-16 encoding completely figured out just yet.

Focus on absorbing what you can for now, and make sure to write some code and build some applications to apply this knowledge. With practice, those initially challenging concepts will start to make more sense over time. This journey is all about gradual progress towards mastery—so be patient with yourself and keep at it.

More strings in the future

We’ve delved into the basics of strings pretty thoroughly. While there are more advanced topics like Tagged Template Literals and pattern matching that fit under the umbrella of text handling, it’s best to tackle those on a more advanced belt. For now, focusing on these fundamental concepts will give you a strong start. Once you're comfortable, we can explore those cool, advanced features that add even more power and flexibility to your JavaScript toolkit.

Study Style Notes

What are JavaScript Strings?

  • Definition: Strings represent text in JavaScript. They are an unchangeable, ordered sequence of 16-bit values, typically representing Unicode characters.

String Length and Indexing

  • Length: The total number of characters in a string.
  • Indexing: JavaScript uses zero-based indexing:
    • The first character is at index 0.
    • The second character is at index 1, and so on.

UTF-16 Encoding and Surrogate Pairs

  • Encoding: JavaScript strings use UTF-16 encoding.
  • Surrogate Pairs: Some special characters require two units to represent a single character.

Including Strings in JavaScript

  • Delimiters: Strings can be wrapped in:
    • Single quotes (' '),
    • Double quotes (" "), or
    • Backticks (`).

Multi-Line Strings

  • ES5+: Use backticks (template literals) to naturally break strings across multiple lines.
  • Older Code: Long strings might be broken into smaller parts with the + operator.

Escaping Characters with Backslashes

  • Escape Mechanism: The backslash (\) allows you to include special characters in strings.
    • Example: 'don\'t' uses a backslash to escape the single quote inside the string.

Working with Strings

  • Concatenation: Use the + operator to join strings.
    • Example: 'Hello, ' + 'world!' results in 'Hello, world!'.
  • Comparison: Use === to check equality and !== to check inequality.
  • Length Property: .length returns the number of characters in a string.

Immutability of Strings

  • Immutability: Strings are immutable, meaning methods like .replace() or .toUpperCase() return a new string without changing the original.
    • Example: 'hello'.toUpperCase() returns 'HELLO', but 'hello' remains unchanged.

Template Literals

  • Introduction: Template literals, introduced in ES6, are enclosed in backticks (`).
  • Expression Embedding: Use ${} to embed JavaScript expressions directly in a string.
  • Multi-Line Strings: Template literals can naturally span multiple lines.

Conclusion

  • Focus on Familiarity: Don’t worry about memorizing all the details. Know that these tools exist, and refer to them when needed.
  • Ask for Help: When in doubt, seek help—whether from resources, peers, or even ChatGPT!