String.prototype.charAt()

Returns the single UTF-16 code unit at a given index, or an empty string when the index is out of range.

Signature
charAt(index)
  • Added in JavaScript ECMAScript 1

Parameters

ParameterTypeDescription
$indexoptionalnumber= 0Zero-based index of the character to return. Converted to an integer; undefined becomes 0.

Return value

stringA string containing exactly one UTF-16 code unit at the given index, or an empty string if the index is outside 0 – str.length - 1.

charAt() is the original single-character accessor and predates bracket notation on strings. For an in-range index it is equivalent to str[i]; the difference is entirely in the edge cases.

Its distinguishing behaviour

  • Out of range returns "", not undefined. That means str.charAt(i).toUpperCase() never throws, which is why it still turns up in defensive parsing loops.
  • Negative indexes are just out of range. "abc".charAt(-1) is "", not "c". Reach for at() when you want end-relative access.
  • The index is coerced to an integer. charAt(1.9) truncates to 1, and charAt() with no argument, charAt(undefined), charAt(null), charAt("foo") and charAt(NaN) all read index 0. That last group is a real source of silent bugs: a mistyped variable does not throw, it quietly gives you the first character.

When to use it today

In new code, bracket access is shorter and at() is more expressive. charAt() earns its place when an empty-string fallback is genuinely convenient, or when you are reading code written before ES5 made str[i] standard.

It returns one code unit, so it splits emoji and other astral characters in half.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Uppercase the first letter of a word for display
  • Walk a string index by index in a hand-written tokenizer
  • Peek at the next character in a parser without risking undefined
  • Read a fixed-position flag character out of a formatted record

Frequently asked questions

What is the difference between charAt(i) and str[i]?

They agree for valid indexes, but an out-of-range charAt() returns an empty string while bracket access returns undefined. charAt() also converts its argument to an integer, so charAt(undefined) reads index 0, while bracket access uses the value directly as a property name.

Why does charAt() return the first character when I pass undefined?

The index is converted to an integer, and undefined, null, NaN and non-numeric strings all convert to 0. Guard the value yourself if a missing index should be an error.

How do I get the last character with charAt()?

Write str.charAt(str.length - 1), because charAt() treats negative indexes as out of range. str.at(-1) does the same thing in one step.

More examples

Indexing every character

The classic index loop and charAt() produce one code unit per step. Spreading the string is equivalent here but would keep an emoji intact, which the index loop would not.

Example · javascript
const word = "cat";
for (let i = 0; i < word.length; i++) {
  console.log(i, word.charAt(i));
}
// 0 c
// 1 a
// 2 t

// Same result, shorter, and code-point aware:
console.log([...word].join("|")); // c|a|t

Empty string vs undefined as a fallback

charAt() lets .toUpperCase() run safely on the empty row, but the result is an indistinguishable empty string. at() returns undefined there, so ?? can supply a real placeholder.

Example · javascript
const rows = ["active", "", "pending"];
for (const r of rows) {
  const initial = r.charAt(0).toUpperCase();
  console.log(JSON.stringify(initial) + " | " + (r.at(0) ?? "n/a"));
}
// "A" | a
// "" | n/a
// "P" | p

Discussion

  • Be the first to comment on this lesson.