String.prototype.charAt()
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.
Syntax
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
Browser compatibility
| Desktop | Mobile | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | WebView Android | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | |
charAt |
1 |
12 |
1 |
3 |
3 |
1 |
1 |
18 |
4 |
10.1 |
1 |
1.0 |
See also
String.prototype.indexOf()String.prototype.lastIndexOf()String.prototype.charCodeAt()String.prototype.codePointAt()String.prototype.split()String.fromCodePoint()- JavaScript has a Unicode problem – Mathias Bynens
© 2005–2021 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charAt