Strings

A string is a sequence of characters — a name, a sentence, a whole web page. This lesson covers creating strings, escaping special characters, reading individual characters, and an important rule: strings can never be changed in place.

Creating strings

Strings can be written with double quotes, single quotes or backticks:

JS quotes.js
const a = "double quotes";
const b = 'single quotes';
const c = `backticks`;

console.log(a, b, c);
console.log(typeof c);
Output
double quotes single quotes backticks
string

Single and double quotes behave identically; pick one and be consistent (Prettier defaults to double). Backticks create template literals, which can insert values and span lines — they get their own lesson (15).

Quotes inside strings

Use the other kind of quote, or escape the quote with a backslash:

JS inner-quotes.js
console.log("It's raining");
console.log('She said "hi"');
console.log('It\'s escaped');
console.log(`Both ' and " work here`);
Output
It's raining
She said "hi"
It's escaped
Both ' and " work here

Escape sequences

SequenceMeaning
\nNew line
\tTab
\\A literal backslash
\' \"A quote that doesn't end the string
\u00e9A Unicode character by code (é)
JS escapes.js
console.log("Line one\nLine two");
console.log("Name:\tAda");
console.log("C:\\Users\\ada");
console.log("caf\u00e9");
Output
Line one
Line two
Name:	Ada
C:\Users\ada
café

Length and characters

Every string has a length. Individual characters are read by position, starting from 0:

JS access.js
const word = "JavaScript";

console.log(word.length);
console.log(word[0]);
console.log(word[4]);
console.log(word.at(-1));
console.log(word[50]);
Output
10
J
S
t
undefined

at() accepts negative numbers to count from the end: at(-1) is the last character. Reading past the end gives undefined, not an error.

Strings are immutable

You can't change a character inside a string. Assigning to a position silently does nothing:

JS immutable.js
let greeting = "hello";
greeting[0] = "J";
console.log(greeting);

greeting = "J" + greeting.slice(1);
console.log(greeting);
Output
hello
Jello

Every string method returns a new string and leaves the original untouched. To "change" a string, build a new one and assign it back to the variable.

Joining strings

JS concat.js
const first = "Grace";
const last = "Hopper";

console.log(first + " " + last);
console.log(first.concat(" ", last));
console.log(`${first} ${last}`);

let report = "Results:";
report += " 3 passed";
console.log(report);
Output
Grace Hopper
Grace Hopper
Grace Hopper
Results: 3 passed

All three give the same result. Template literals are usually the most readable when mixing text and values.

Comparing strings

=== compares strings exactly, including case and spaces. For case-insensitive checks, normalise both sides first:

JS compare.js
const input = "  Yes ";

console.log(input === "yes");
console.log(input.trim().toLowerCase() === "yes");
Output
false
true

Unicode and emoji

JavaScript strings are stored as UTF-16 code units. Most characters take one unit, but many emoji take two, which can make length surprising:

JS unicode.js
const heart = "❤";
const rocket = "🚀";

console.log(heart.length, rocket.length);
console.log([...rocket].length);
Output
1 2
1

Spreading a string into an array ([...str]) splits by whole characters (code points), which is a better count for text containing emoji.

Try it yourself

Try it yourself
Console output