JavaScript String charAt() Method

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Instance method

What You’ll Learn

String.prototype.charAt() returns one UTF-16 code unit at a zero-based index (same API as MDN String.prototype.charAt()). It is a classic, legacy-friendly way to read a character. This tutorial covers out-of-range "", why negatives do not work, comparisons with at() and brackets, five examples, and try-it labs.

01

Kind

Instance method

02

Returns

1 char or ""

03

Negative?

No

04

vs at()

Legacy-friendly

05

Mutates?

No

06

Baseline

Widely available

Introduction

charAt() is one of the oldest ways to read a character from a string. You pass a zero-based index and get back a one-character string — or "" when that index does not exist.

It is still widely used in tutorials and older code. For new apps that need “last character” access, prefer at(-1). Keep charAt() when you want a predictable empty string for bad indexes, or when matching legacy examples.

💡
Beginner tip

Out of range, charAt() returns "" — not undefined. That is different from at() and from str[i].

This page is part of JavaScript String Methods. Related topics include charCodeAt() and at().

Understanding the charAt() Method

charAt(index) returns a new string with a single UTF-16 code unit from the chosen position. It does not change the original string.

  • Indexes are zero-based — 0 is the first character.
  • The last character is at str.length - 1.
  • Missing position — returns "".
  • Negative indexes are not supported — use at(-1) instead.

📝 Syntax

General form of String.prototype.charAt:

JavaScript
str.charAt(index)

Parameters

  • index — zero-based position of the character. Converted to an integer (undefined becomes 0).

Return value

A string with the single UTF-16 code unit at that position, or an empty string "" if the index is outside 0 … str.length - 1.

Common patterns

JavaScript
"Hello".charAt(0);              // "H"
"Hello".charAt(4);              // "o"
"Hello".charAt(10);             // ""
"Hello".charAt("Hello".length - 1); // "o"

// Prefer at(-1) for last-character access in new code:
"Hello".at(-1);                 // "o"

⚡ Quick Reference

GoalCode
First characterstr.charAt(0)
Last characterstr.charAt(str.length - 1)
Out of range""
No index argumentstr.charAt() → like charAt(0)
Modern last charstr.at(-1)

🔍 At a Glance

Four facts to remember about String.charAt().

Returns
string

One unit or ""

Negative
not supported

Use at(-1) instead

Out of range
""

Empty string miss

Mutates
no

Strings stay immutable

📋 charAt() vs at() vs str[i]

charAt(i)at(i)str[i]
Negative indexReturns ""From the endundefined (property "-1")
Out of range""undefinedundefined
Index coercionTo integer (undefined0)To integerUsed as property name
Best forLegacy / empty-string missesReadable end accessSimple positive indexes

Examples Gallery

Examples follow MDN String.charAt() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

Read characters with zero-based indexes.

Example 1 — Basic charAt()

MDN demo: read a character counting from the start.

JavaScript
const sentence = "The quick brown fox jumps over the lazy dog.";
const index = 4;

`The character at index ${index} is ${sentence.charAt(index)}`;
// "The character at index 4 is q"
Try It Yourself

How It Works

Index 4 lands on "q" in "quick" (after "The "). Counting always starts at 0.

Example 2 — Several Indexes (Including Default & Out of Range)

MDN-style walkthrough of "Brave new world".

JavaScript
const anyString = "Brave new world";

anyString.charAt();     // "B"  (no index → 0)
anyString.charAt(0);    // "B"
anyString.charAt(1);    // "r"
anyString.charAt(2);    // "a"
anyString.charAt(3);    // "v"
anyString.charAt(4);    // "e"
anyString.charAt(999);  // ""
Try It Yourself

How It Works

Missing or undefined index becomes 0. A far-too-large index does not throw — you get an empty string.

📈 Practical Patterns

Last character, comparisons, and Unicode caution.

Example 3 — Last Character with length

Classic pattern before at(-1) existed.

JavaScript
function returnLast(str) {
  return str.charAt(str.length - 1);
}

returnLast("my-invoice01");  // "1"
returnLast("my-invoice02");  // "2"
returnLast("");              // ""
Try It Yourself

How It Works

For an empty string, length - 1 is -1, and charAt(-1) returns "" — useful to know when migrating to at(), which would return undefined.

Example 4 — Compare charAt, at, and Brackets

Same positions, three different APIs.

JavaScript
const s = "abc";

s.charAt(1);   // "b"
s.at(1);       // "b"
s[1];          // "b"

s.charAt(10);  // ""
s.at(10);      // undefined
s[10];         // undefined

s.charAt(-1);  // ""
s.at(-1);      // "c"
s[-1];         // undefined
Try It Yourself

How It Works

Positive indexes usually agree. Differences show up for negatives and missing positions — choose the API that matches the miss value you want.

Example 5 — Surrogate Pairs (Emoji Caution)

MDN note: charAt may return a lone surrogate, not a full character.

JavaScript
const str = "𠮷𠮾";

str.charAt(0);  // "\ud842"  (lone surrogate — not a full character)
str.charAt(1);  // "\udfb7"

// Prefer code-point APIs for the full character:
String.fromCodePoint(str.codePointAt(0));  // "𠮷"
[...str][0];                               // "𠮷"
Try It Yourself

How It Works

Many characters above U+FFFF need two UTF-16 code units. Avoid hand-pairing surrogates with charAt — use built-in code-point helpers instead.

🚀 Common Use Cases

  • Reading a known index — first letter, digit at position n.
  • Legacy last charactercharAt(str.length - 1) in older samples.
  • Empty-string misses — when you prefer "" over undefined.
  • Teaching indexes — pair with length for beginners.
  • Migrating to at() — replace end-access patterns with at(-1).
  • Not for full emoji — use code points / segmenters when graphemes matter.

🧠 How charAt() Resolves an Index

1

Receive an index

Convert to an integer (undefined becomes 0).

Input
2

Check the range

Valid positions are 0 through length - 1.

Bounds
3

Read one code unit

Return that character as a new string.

Read
4

Or return ""

If the index is outside the string (including negatives).

📝 Notes

  • charAt() returns one UTF-16 code unit, not always one visible emoji.
  • Out-of-range indexes return "", not undefined.
  • charAt(-1) is not the last character — use at(-1) or charAt(length - 1).
  • Calling charAt() with no argument is the same as charAt(0).
  • Fractional indexes are truncated toward zero (like other string index methods).
  • Prefer at() for new code when you need relative indexing from the end.

Browser & Runtime Support

String.prototype.charAt() is Baseline Widely available — supported across browsers for many years (long before at()).

Baseline · Widely available

String.charAt()

Safe everywhere. Prefer at(-1) when you need last-character access in modern code.

Universal Widely available
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Internet Explorer No native support · Use a polyfill
Polyfill
Opera Supported · Modern versions
Full support
Samsung Internet Supported · Android
Full support
Bun Supported · JavaScript runtime
Supported
Deno Supported · JavaScript runtime
Supported
Node.js Supported · Server runtime
Supported
Android WebView Supported · Modern WebView
Full support
charAt() Excellent

Bottom line: Use String.charAt() for zero-based character access. Remember out-of-range returns "", negatives are not supported, and emoji may span two code units.

Conclusion

String.prototype.charAt() is the classic way to read one UTF-16 code unit by index, returning "" when the position is missing. Learn it for legacy code — and reach for at(-1) when you want clear end access.

Continue with charCodeAt(), at(), or the String constructor.

💡 Best Practices

✅ Do

  • Use charAt(i) for clear positive-index reads
  • Use charAt(str.length - 1) when matching older tutorials
  • Prefer at(-1) for last-character access in new code
  • Pair with length when explaining zero-based indexes
  • Use code-point helpers for full emoji characters

❌ Don’t

  • Expect charAt(-1) to return the last character
  • Assume charAt(0) on an emoji returns the whole emoji
  • Treat out-of-range charAt like undefined
  • Hand-pair surrogates with charAt(i) and charAt(i + 1)
  • Forget strings are immutable — charAt never edits in place

Key Takeaways

Knowledge Unlocked

Five things to remember about String.charAt()

Zero-based character access with empty-string misses.

5
Core concepts
🔙 02

Last

length - 1

Pattern
03

Negatives

not supported

Feature
04

vs at

prefer at(-1)

Compare
📄 05

Mutates

no

Immutable

❓ Frequently Asked Questions

String.prototype.charAt(index) returns a new string with the single UTF-16 code unit at that zero-based index. If the index is out of range, it returns an empty string "".
No. charAt(-1) returns "". To read from the end, use at(-1) or charAt(str.length - 1).
at() supports negative indexes and returns undefined when out of range. charAt() does not support negatives and returns "" for out-of-range indexes.
charAt() converts the index to an integer (undefined becomes 0) and returns "" out of range. Bracket notation uses the value as a property name and returns undefined when missing.
Not always. charAt() returns one UTF-16 code unit. Many emoji use two code units (a surrogate pair). Prefer codePointAt() / String.fromCodePoint() or [...str] for full code points.
No. Strings are immutable. charAt() returns a new one-character string (or "").
Did you know?

charAt() existed for decades before at(). Many older books still teach str.charAt(str.length - 1) for the last character — today str.at(-1) is clearer, but both remain correct.

More String Methods

Return to the hub for slice, trim, replace, and more.

String methods hub →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful