charAt()越界返回空字符串"",不支持负索引;at()越界返回undefined,支持负索引(如-1取末字符),语义更清晰、利于错误判断。

String.prototype.charAt() 和 at() 在处理越界索引时表现不同:charAt() 遇到无效索引(如负数、超出长度)会返回空字符串 "";而 at() 支持负数索引(从末尾倒数),越界时返回 undefined。
charAt() 的越界行为:静默返回空字符串
charAt() 接收一个数字参数,将其转为整数后尝试获取对应位置的字符。若索引小于 0、大于等于字符串长度,或不是有效整数(如 NaN),它都返回空字符串。
- "hello".charAt(-1) → ""
- "hello".charAt(10) → ""
- "hello".charAt("2") → "l"(自动转换为数字 2)
- "hello".charAt(NaN) → ""(NaN 转为 0,但 "hello"[0] 是 "h"?注意:实际是先 ToInteger(NaN) → 0,所以返回 "h";但 charAt(Infinity) → "",因为 ToInteger(Infinity) → 0?不准确——规范中 ToInteger(Infinity) 是 0,但实际测试中 "x".charAt(Infinity) 返回 "",因内部处理逻辑限制索引范围为 [0, length) 且非有限数直接判定越界)
关键点:它不会报错,也不支持倒序访问,所有越界情况统一归为 "",容易掩盖逻辑错误。
at() 的越界行为:明确返回 undefined,支持负索引
at() 是 ES2022 新增方法,接受任意值,经 ToInteger 处理后计算有效索引。负数表示从末尾开始(-1 是最后一个字符),越界时明确返回 undefined。
- "hello".at(-1) → "o"
- "hello".at(10) → undefined
- "hello".at(-10) → undefined
- "hello".at("2") → "l"(同样会 ToInteger)
优势在于语义清晰:返回 undefined 明确提示“查无此位”,配合可选链或空值合并(??)更易写出健壮代码,比如 str.at(-1) ?? 'default'。
实际使用建议
- 需要倒序取字符(如获取末位)→ 优先用 at()
- 需兼容老旧环境(IE、Node.js < 16.6)→ 只能用 charAt(),并手动处理负索引(如
str[str.length + idx]) - 做越界校验时 → at() 的
undefined更利于判断,charAt() 的""可能与真实空字符混淆(如字符串含 "\0" 或纯空格) - 性能敏感场景 → 两者差异极小,无需刻意优化;但频繁越界访问时,at() 的语义反馈对调试更有价值
两种方法核心区别不在性能,而在错误信号强度和负索引支持。现代项目推荐用 at(),既简洁又可靠;维护旧代码时理解 charAt() 的静默特性可避免误判越界逻辑。

















