jsguides

String.prototype.charAt()

charAt(index)

The charAt() method returns the character at the specified index in a string. Characters are indexed from 0 to length - 1. This is the standard way to access individual characters when you need explicit index-based retrieval.

Syntax

string.charAt(index)
  • index: An integer representing the position of the character to retrieve. If omitted, defaults to 0. If negative or greater than or equal to length, returns an empty string.
  • Returns: A string containing the character at the specified index, or an empty string if the index is out of bounds.

TypeScript Signature

interface String {
  charAt(index: number): string;
}

The TypeScript signature confirms that charAt() takes a single number argument and always returns a string, never undefined or null. This consistency is important when you chain the result into other string operations like concatenation or slicing. Here are several examples showing how different index values produce different results:

Basic Examples

const text = "Hello";

console.log(text.charAt(0)); // "H"
console.log(text.charAt(1)); // "e"
console.log(text.charAt(4)); // "o"
console.log(text.charAt(5)); // "" (out of bounds → empty string)
console.log(text.charAt(-1)); // "" (negative → empty string)

charAt() vs bracket notation

Using charAt() for character retrieval is the older, more explicit approach. Bracket notation, introduced in ES5, offers a terser syntax but with an important behavioral difference. Two common ways to access a character exist: charAt() and bracket notation string[index]. They behave identically for valid indices, but differ critically when the index is out of bounds:

const text = "Hi";

console.log(text.charAt(0));   // "H"
console.log(text.charAt(1));   // "i"
console.log(text.charAt(5));   // "" (empty string)

console.log(text[0]);          // "H"
console.log(text[1]);          // "i"
console.log(text[5]);          // undefined (not empty string!)

The key difference: bracket notation returns undefined for out-of-bounds indices, while charAt() returns an empty string. This makes charAt() safer when you concatenate the result—you won’t accidentally get the string "undefined" in your output.

Unicode and UTF-16 code units

JavaScript strings are UTF-16 encoded. This means each “character” position corresponds to a 16-bit code unit, not necessarily a complete Unicode codepoint:

const emoji = "😀";

console.log(emoji.length);     // 2 (two UTF-16 code units)
console.log(emoji.charAt(0));  // "�" (first surrogate: 0xD83D)
console.log(emoji.charAt(1));  // "�" (second surrogate: 0xDE00)

// Use spread operator or for-of for actual Unicode characters
console.log([..."😀"][0]);      // "😀"

For simple ASCII and common characters, charAt() works as expected. For emojis and supplementary characters, use the spread operator or codePointAt() instead.

Now that you know how charAt() handles individual positions, here is how to combine it with a loop to walk through every character in a string. The standard idiom uses a for loop with an incrementing index, calling charAt() on each position:

Iteration Pattern

A common pattern to iterate over each character in a string:

const str = "hello";

for (let i = 0; i < str.length; i++) {
  console.log(`Index ${i}: ${str.charAt(i)}`);
}
// Output:
// Index 0: h
// Index 1: e
// Index 2: l
// Index 3: l
// Index 4: o

The examples above cover the everyday cases, but charAt() has a few non-obvious behaviors worth knowing about. The following snippet tests boundary inputs — omitted index, Infinity, and NaN — to show what the method returns in each situation:

Edge Cases

const text = "test";

console.log(text.charAt());     // "t" (defaults to index 0)
console.log(text.charAt(0));    // "t"
console.log(text.charAt(Infinity)); // "" (out of bounds)
console.log(text.charAt(NaN));  // "t" (NaN coerced to 0)

When charAt() Is Useful

charAt() is still a good choice when you want the simplest possible character lookup and you do not need negative indexing. It has a very predictable contract: give it an index, get back a one-character string or an empty string if the index is out of bounds. That makes it easy to drop into older code or straightforward parsing logic.

Because it returns an empty string instead of undefined, charAt() can be slightly friendlier when you concatenate the result into another string. The tradeoff is that missing values are easier to miss. For logic that needs to detect a missing character, at() or an explicit bounds check may be clearer.

Unicode Caveat

charAt() works at the UTF-16 code-unit level, which means it is not a full Unicode character reader. Emoji and other supplementary characters can be split into surrogate halves. If your input can contain those values, prefer at(), codePointAt(), or iteration techniques that operate on full code points instead of code units.

That detail matters most in text processing code that handles user-generated content or non-English languages. If the data is mostly ASCII, charAt() is usually fine. If not, make sure the code is doing the kind of character handling you actually need.

Browser Compatibility

BrowserVersion
Chrome1+
Firefox1+
Safari1+
Edge12+
Node.js0.1.0+

Universal support across all JavaScript environments.

See Also