JS: String Index and Code Unit

By Xah Lee. Date: . Last updated: .

What is javascript string

JavaScript string is sequence of code units that represent Unicode characters.

(Each “code unit” may be “half of a character” or full character.)

How is string indexed

JavaScript string is indexed by code units. The first code unit has index 0, etc.

If the string contains a character whose Code Point (Char ID) is ≥ 2^16 (e.g. 🦋 (U+1F98B: BUTTERFLY)) , that character is represented by two code units, thus occupies 2 indexes. Result of string functions may be unexpected.

What is code unit?

A Code Unit, is 2 bytes unit of a Unicode character in Unicode UTF-16 Encoding .

Code unit explained

  1. JavaScript string and character are based on Unicode standard, version 5.1 or later.
  2. In unicode, each character has an integer ID, called Code Point.
  3. Unicode specifies several encoding standards, most popular ones are UTF-8 and UTF-16.
  4. Encoding means, a standard that translate a character into sequence of Bytes. [see Unicode: Character Set, Encoding, UTF-8, Code Point]
  5. In UTF-16 encoding, each character is 2 or 4 bytes, depending on the character. (each 2 bytes is considered a unit, called code unit.)
  6. For characters whose codepoint is less than 2^16, the encoding of that char in UTF-16 is 2 bytes. Otherwise, it's 4 bytes.
  7. JavaScript defines element of string as sequence of 2-byte values of the characters encoded in UTF-16. That is, first encode the character in the string to bits by UTF-16, you get 2 or 4 bytes. Then, group every 2 bytes as a code unit. Then, index 0 is first 2-bytes unit, index 1 is second 2-bytes unit, etc. This means, when a string contain character whose codepoint is ≥ 2^16, the result of any string method, may be unexpected, because the index does not correspond to character.

Example: difference of character and code unit

console.assert("🦋".length === 2);

Here is a example with String.prototype.slice method with unexpected result.

// we want to take the substring abc
console.log("🦋abc".slice(1));
// �abc

// result is not what we want

What characters create problems?

Characters outside of Unicode Basic Multilingual Plane. Typically emoji.

How to go thru character (not code unit)

If you have a string that contains characters outside of Unicode Basic Multilingual Plane , the result of any string method may be unexpected.

Solution is to use for-of Loop or Array.from to go thru string.

Real length: number of characters in string