String.prototype.charCodeAt(index)
charCodeAt returns the 16-bit UTF-16 code unit at the given
position, as a number between 0 and 65535. If the
index is out of range it returns NaN — not an exception, and not
undefined.
Basic usage
const s = "hello";
s.charCodeAt(0); // 104 ('h')
s.charCodeAt(1); // 101 ('e')
s.charCodeAt(99); // NaN (out of range)
UTF-16: two units for one character
JavaScript strings are sequences of UTF-16 code units, not Unicode code
points. Characters outside the Basic Multilingual Plane (code points above
U+FFFF) are stored as surrogate pairs and occupy two
positions:
const s = "\u{1F600}"; // 😀
s.length; // 2
s.charCodeAt(0); // 55357 (0xD83D, high surrogate)
s.charCodeAt(1); // 56832 (0xDE00, low surrogate)
If you need the actual character (code point 128512), use
codePointAt instead.
Common pattern: iterating "characters"
for (let i = 0; i < s.length; i++) {
console.log(s.charCodeAt(i).toString(16));
}
This loop prints code units. To iterate real code points, prefer the string iterator, which is surrogate-pair aware:
for (const ch of "\u{1F600}abc") {
console.log(ch.codePointAt(0).toString(16));
// 1f600, 61, 62, 63
}
Practical uses
- Character arithmetic:
'a'.charCodeAt(0) + 1→98('b'). - Sorting and comparison logic where locale collators are not wanted.
- Simple checksums and encoders where each unit must be inspected.
Remember:
charCodeAt never splits a surrogate
pair for you. Mixing it with emoji input is a classic source of corrupted
strings.See also
codePointAt— full code points.fromCodePoint— the inverse operation.