Added so that reading the last character stops requiring arithmetic. Bracket notation cannot take a negative index, and charAt will not either.
String methodES2022Live demo
Common call
s.at(-1)
Returns
one character, or undefined
Replaces
s[s.length - 1] and s.charAt(s.length - 1)
Watch out
out of range is undefined, while charAt gives ""
string.at(indexindex — Position to read. Negative counts back from the end, so -1 is the last character. Out of range gives undefined rather than throwing.type: number · required)
→ string | undefined
Demo
Live evaluation
Try:
Inputs
sstringthe source string
indexnumberindex (may be negative)
Output
'abcdef'.at(0)
'a'
Negative indices are the entire reason this method exists: at(-1) is the last character, with no reference to length anywhere. The out-of-range case returns undefined, which is the meaningful difference from charAt — charAt(99) returns an empty string, so a truthiness check treats a missing character and a real one very differently depending on which method you used. Neither one throws.
Parameters
Name
Type
Required
Description
index
number
yes
Position to read. Negative counts back from the end, so -1 is the last character. Out of range gives undefined rather than throwing.
Return value
string | undefined — A one-character string, or undefined when the index is out of range. charAt returns an empty string in that case instead.
Common patterns
Read the last character
The reason the method was added.
constlast = s.at(-1);
Test a trailing character
Clearer than a length calculation.
if (path.at(-1) !== '/') path += '/';
Capitalise the first letter
at reads it; slice takes the rest.
consttitle = s.at(0).toUpperCase() + s.slice(1);
Examples
1. First character
'abcdef'.at(0)
Returns
'a'
2. Last character
'abcdef'.at(-1)
Returns
'f'
3. Out of range
'abcdef'.at(99)
Returns
undefined
4. charAt differs
'abcdef'.charAt(99)
Returns
''
5. Brackets differ
'abcdef'[99]
Returns
undefined
6. Negative brackets
'abcdef'[-1]
Returns
undefined
Pitfalls
1. Bracket notation does not accept negatives
s[-1] is not an error and not the last character — it looks up a property literally named "-1", which does not exist, so you get undefined. This is why the method was added at all.
Property lookup
'abc'[-1]
undefined
Use at
'abc'.at(-1)
'c'
2. at and charAt disagree when out of range
at gives undefined, charAt gives an empty string. Both are falsy, so a simple if behaves the same — but concatenation does not, and "undefined" appearing in output is usually traced back to exactly this.
Stringifies badly
'x' + 'abc'.at(99)
'xundefined'
charAt, or default
'x' + ('abc'.at(99) ?? '')
'x'
3. It reads a code unit, not a character
Like every index-based string operation, at works in UTF-16. The first "character" of a string starting with an emoji is half a surrogate pair, which renders as a replacement glyph.
Half an emoji
'\u{1F600}a'.at(0)
'\ud83d'
Spread first
[...'\u{1F600}a'].at(0)
'\u{1F600}'
4. ES2022 — check your runtime
Node 16.6+ and 2021-era browsers. Older targets need the length arithmetic, or slice(-1) which has worked since ES3 and returns an empty string rather than undefined.
Missing
s.at(-1)
TypeError: s.at is not a function
slice(-1)
s.slice(-1)
last character, or ""
When to use
Use it
Reading the last character, or the nth from the end
Any single-character read where the index may be negative
Replacing s[s.length - 1] for readability
Reach for something else
You want a substring, not one character → slice
You need an empty string rather than undefined → charAt
The text contains emoji → spread into an array of code points
at for anything involving the end of the string, since it is the only one that takes a negative index. Brackets are fine and fastest for a known non-negative index. charAt is worth knowing mainly because it returns an empty string rather than undefined when out of range.