String.prototype.charCodeAt()

Returns the numeric UTF-16 code unit value of the character at a given index, or NaN if out of range.

Signature
charCodeAt(index)
  • Added in JavaScript ECMAScript 1

Parameters

ParameterTypeDescription
$indexnumberZero-based index of the character whose code unit is returned. Converted to an integer; undefined becomes 0.

Return value

numberAn integer between 0 and 65535 representing the UTF-16 code unit at the given index, or NaN when the index is outside 0 – str.length - 1.

charCodeAt() converts a character to its numeric UTF-16 code unit, the inverse of String.fromCharCode(). It is the workhorse behind hand-rolled hashes, checksums, character-class tests and any code that needs arithmetic on letters.

The 16-bit ceiling

The return value never exceeds 65535. Characters above U+FFFF are stored as two code units, so charCodeAt() gives you a surrogate half: a leading surrogate in the range 0xD800–0xDBFF or a trailing one in 0xDC00–0xDFFF. Neither is a usable character on its own. Use codePointAt() when the input can contain emoji, rare CJK, or mathematical alphanumerics.

NaN, not an exception

An out-of-range index returns NaN, which then poisons every arithmetic operation downstream — a running total becomes NaN and stays there. Check with Number.isNaN(), or bound the loop with str.length.

Common comparisons

For ASCII ranges, comparing code units is faster and clearer than a regular expression: const c = s.charCodeAt(i); c >= 48 && c <= 57 tests for a digit. Remember it is a code-unit comparison, not a locale-aware one — for sorting human-readable text use Intl.Collator instead.

Example

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

When to use it

  • Build a fast non-cryptographic string hash for cache keys
  • Classify a character as a digit or ASCII letter without a regex
  • Implement a Caesar or ROT13 shift over letters
  • Detect surrogate halves before handing text to a legacy encoder

Frequently asked questions

How do I get the ASCII value of a character in JavaScript?

Call str.charCodeAt(index), which returns the UTF-16 code unit — identical to the ASCII value for characters below 128. String.fromCharCode() converts back.

Why does charCodeAt() return 55357 for an emoji?

Because emoji above U+FFFF are stored as a surrogate pair and charCodeAt() only ever returns one 16-bit code unit. Use codePointAt() to get the full code point in one call.

What does charCodeAt() return for an invalid index?

It returns NaN instead of throwing. Test with Number.isNaN(), since NaN silently propagates through any arithmetic that follows.

More examples

A small string hash

Each code unit feeds a rolling multiply-add. The >>> 0 keeps the accumulator an unsigned 32-bit integer; without it the value drifts into floating point and loses precision on long strings.

Example · javascript
function hash(str) {
  let h = 0;
  for (let i = 0; i < str.length; i++) {
    h = (h * 31 + str.charCodeAt(i)) >>> 0; // keep it a uint32
  }
  return h;
}

console.log(hash("hello")); // 99162322
console.log(hash("hellp")); // 99162323
console.log(hash("")); // 0

Shifting letters by code unit

Code-unit arithmetic shifts only the ASCII letter ranges; spaces and punctuation fall through untouched, and applying ROT13 twice restores the original.

Example · javascript
const rot = (s, n) =>
  [...s]
    .map((ch) => {
      const c = ch.charCodeAt(0);
      if (c >= 97 && c <= 122) return String.fromCharCode(((c - 97 + n) % 26) + 97);
      if (c >= 65 && c <= 90) return String.fromCharCode(((c - 65 + n) % 26) + 65);
      return ch;
    })
    .join("");

console.log(rot("Attack at dawn!", 13)); // "Nggnpx ng qnja!"
console.log(rot(rot("Attack at dawn!", 13), 13)); // "Attack at dawn!"

Discussion

  • Be the first to comment on this lesson.