The String object's charAt() method returns a new string consisting of the single UTF-16 code unit located at the specified offset into the string.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Syntax
let character = str.charAt(index)
Parameters
index- An integer between
0andstr.length - 1. If theindexcannot be converted to the integer or noindexis provided, the default is0, so the first character ofstris returned.
Return value
A string representing the character (exactly one UTF-16 code unit) at the specified index. If index is out of range, charAt() returns an empty string.
Description
Characters in a string are indexed from left to right. The index of the first character is 0, and the index of the last character—in a string called stringName—is stringName.length - 1. If the index you supply is out of this range, JavaScript returns an empty string.
If no index is provided to charAt(), the default is 0.
Examples
Displaying characters at different locations in a string
The following example displays characters at different locations in the string "Brave new world":
var anyString = 'Brave new world';
console.log("The character at index 0 is '" + anyString.charAt() + "'");
// No index was provided, used 0 as default
console.log("The character at index 0 is '" + anyString.charAt(0) + "'");
console.log("The character at index 1 is '" + anyString.charAt(1) + "'");
console.log("The character at index 2 is '" + anyString.charAt(2) + "'");
console.log("The character at index 3 is '" + anyString.charAt(3) + "'");
console.log("The character at index 4 is '" + anyString.charAt(4) + "'");
console.log("The character at index 999 is '" + anyString.charAt(999) + "'");
These lines display the following:
The character at index 0 is 'B' The character at index 0 is 'B' The character at index 1 is 'r' The character at index 2 is 'a' The character at index 3 is 'v' The character at index 4 is 'e' The character at index 999 is ''
Getting whole characters
The following provides a means of ensuring that going through a string loop always provides a whole character, even if the string contains characters that are not in the Basic Multi-lingual Plane.
var str = 'A \uD87E\uDC04 Z'; // We could also use a non-BMP character directly
for (var i = 0, chr; i < str.length; i++) {
if ((chr = getWholeChar(str, i)) === false) {
continue;
}
// Adapt this line at the top of each loop, passing in the whole string and
// the current iteration and returning a variable to represent the
// individual character
console.log(chr);
}
function getWholeChar(str, i) {
var code = str.charCodeAt(i);
if (Number.isNaN(code)) {
return ''; // Position not found
}
if (code < 0xD800 || code > 0xDFFF) {
return str.charAt(i);
}
// High surrogate (could change last hex to 0xDB7F to treat high private
// surrogates as single characters)
if (0xD800 <= code && code <= 0xDBFF) {
if (str.length <= (i + 1)) {
throw 'High surrogate without following low surrogate';
}
var next = str.charCodeAt(i + 1);
if (0xDC00 > next || next > 0xDFFF) {
throw 'High surrogate without following low surrogate';
}
return str.charAt(i) + str.charAt(i + 1);
}
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
if (i === 0) {
throw 'Low surrogate without preceding high surrogate';
}
var prev = str.charCodeAt(i - 1);
// (could change last hex to 0xDB7F to treat high private
// surrogates as single characters)
if (0xD800 > prev || prev > 0xDBFF) {
throw 'Low surrogate without preceding high surrogate';
}
// We can pass over low surrogates now as the second component
// in a pair which we have already processed
return false;
}
In an ECMAScript 2016 environment which allows destructured assignment, the following is a more succinct and somewhat more flexible alternative in that it does increment for an incrementing variable automatically (if the character warrants it in being a surrogate pair).
let str = 'A\uD87E\uDC04Z' // We could also use a non-BMP character directly
for (let i = 0, chr; i < str.length; i++) {
[chr, i] = getWholeCharAndI(str, i)
// Adapt this line at the top of each loop, passing in the whole string and
// the current iteration and returning an array with the individual character
// and 'i' value (only changed if a surrogate pair)
console.log(chr)
}
function getWholeCharAndI(str, i) {
let code = str.charCodeAt(i)
if (Number.isNaN(code)) {
return '' // Position not found
}
if (code < 0xD800 || code > 0xDFFF) {
return [str.charAt(i), i] // Normal character, keeping 'i' the same
}
// High surrogate (could change last hex to 0xDB7F to treat high private
// surrogates as single characters)
if (0xD800 <= code && code <= 0xDBFF) {
if (str.length <= (i + 1)) {
throw 'High surrogate without following low surrogate'
}
let next = str.charCodeAt(i + 1)
if (0xDC00 > next || next > 0xDFFF) {
throw 'High surrogate without following low surrogate'
}
return [str.charAt(i) + str.charAt(i + 1), i + 1]
}
// Low surrogate (0xDC00 <= code && code <= 0xDFFF)
if (i === 0) {
throw 'Low surrogate without preceding high surrogate'
}
let prev = str.charCodeAt(i - 1)
// (could change last hex to 0xDB7F to treat high private surrogates
// as single characters)
if (0xD800 > prev || prev > 0xDBFF) {
throw 'Low surrogate without preceding high surrogate'
}
// Return the next character instead (and increment)
return [str.charAt(i + 1), i + 1]
}
Fixing charAt() to support non-Basic-Multilingual-Plane (BMP) characters
While the previous example may be more useful for programs that must support non-BMP characters (since it does not require the caller to know where any non-BMP character might appear), in the event that one does wish, in choosing a character by index, to treat the surrogate pairs within a string as the single characters they represent, one can use the following:
function fixedCharAt(str, idx) {
let ret = ''
str += ''
let end = str.length
let surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g
while ((surrogatePairs.exec(str)) != null) {
let lastIdx = surrogatePairs.lastIndex
if (lastIdx - 2 < idx) {
idx++
} else {
break
}
}
if (idx >= end || idx < 0) {
return ''
}
ret += str.charAt(idx)
if (/[\uD800-\uDBFF]/.test(ret) && /[\uDC00-\uDFFF]/.test(str.charAt(idx + 1))) {
// Go one further, since one of the "characters" is part of a surrogate pair
ret += str.charAt(idx + 1)
}
return ret
}
Specifications
| Specification |
|---|
| ECMAScript (ECMA-262) The definition of 'String.prototype.charAt' in that specification. |
Browser compatibility
The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
charAt | Chrome Full support 1 | Edge Full support 12 | Firefox Full support 1 | IE Full support 3 | Opera Full support 3 | Safari Full support 1 | WebView Android Full support 1 | Chrome Android Full support 18 | Firefox Android Full support 4 | Opera Android Full support 10.1 | Safari iOS Full support 1 | Samsung Internet Android Full support 1.0 | nodejs Full support 0.1.100 |
Legend
- Full support
- Full support
