JavaScript实现ASCII转字符串为何输出异常Unicode结果?
问题根因
代码存在两个核心逻辑错误:
- 遍历语法使用错误:
for...in语句设计目的是遍历对象的可枚举属性,遍历数组、字符串这类顺序集合时,拿到的是字符串类型的属性名/索引值,不是集合内存储的元素本身。你的第一个循环看似输出了正确的码点数组,实际是因为codePointAt()会自动把传入的字符串索引转成数字,属于碰巧生效;第二个循环中你拿到的s实际是"0"、"1"、"2"、"3"、"4"这几个索引字符串,根本不是之前存入的ASCII码值,传入字符转换方法后得到的自然是异常内容。 - 编解码API不匹配:编码阶段你用了支持完整Unicode字符集的
codePointAt()方法取码点,解码阶段却用了仅支持单个UTF-16码元的fromCharCode()方法,后续如果转换emoji、生僻汉字这类占两个UTF-16码元的字符,就算索引逻辑正确,也会出现转码乱码的问题。
修复方法
修正遍历逻辑,同时匹配编解码API即可,参考代码如下:
let str = "hello"; let codePoints = [] // 用for...of直接遍历字符串拿到单个字符,避免错误拿到索引 for (const char of str) { codePoints.push(char.codePointAt(0)) } console.log(codePoints) // 正确输出码点数组:[104, 101, 108, 108, 111] let backStr = '' // 遍历码点数组时直接拿到存储的码点值 for (const code of codePoints) { // 匹配编码阶段的codePointAt,使用fromCodePoint做解码,兼容所有Unicode字符 backStr += String.fromCodePoint(code) } console.log(backStr) // 正确输出原始字符串:"hello"
如果需要更精简的实现,也可以直接用内置方法完成转换:
const str = "hello"; // 转码点数组 const codePoints = Array.from(str, c => c.codePointAt(0)); // 直接传入码点列表拼接为原始字符串 const backStr = String.fromCodePoint(...codePoints);
内容的提问来源于stack exchange,提问作者Dshiz
相关产品推荐
相关产品推荐

