You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何直接对TypedArray用map与转Array后用map的十六进制结果不同?

TypedArray.map与普通数组map结果不一致的原因解析

我们的目标是将字符串转换为十六进制,但发现直接对TypedArray调用map方法,与先通过Array.from将TypedArray转为普通数组后再调用map方法,得到的结果不一致。相关代码及运行结果如下:

var buf = new TextEncoder().encode('hello');

var ret = '';
for (var b of buf) ret += b.toString(16).padStart(2, '0').slice(-2);

console.log(
    '\n',
    buf.join(), // 104,101,108,108,111
    '\n',
    buf.map(x => x.toString(16).padStart(2, '0').slice(-2)).join(''), // 6865000 
    '\n',
    Array.from(buf).join(), // 104,101,108,108,111 
    '\n',
    Array.from(buf).map(x => x.toString(16).padStart(2, '0').slice(-2)).join(''), // 68656c6c6f 
    '\n',
    ret, // 68656c6c6f 
    '\n',
    decodeURIComponent('%' + ret.match(/.{1,2}/g).join('%')) // hello
);
/*
 104,101,108,108,111 
 6865000 
 104,101,108,108,111 
 68656c6c6f 
 68656c6c6f 
 hello
*/

核心原因

TypedArray的map方法会保留原数组的类型,它会把回调函数的返回值强制转换为原TypedArray的元素类型;而普通数组的map没有类型约束,会直接保留回调的返回结果。

具体分析

  1. buf是TextEncoder.encode生成的Uint8Array,每个元素都是0-255的整数。
  2. 调用buf.map时,回调返回的是十六进制格式的字符串(比如"68"、"6c"):
    • 对于纯数字字符串(如"68"),Uint8Array会将其转为对应的整数68,这一步没问题;
    • 对于包含字母的十六进制字符串(如"6c"),直接转整数会被识别为十进制,parseInt("6c")结果是NaN,而Uint8Array会把NaN强制转为0;
    • 最终buf.map返回的Uint8Array元素是[68, 65, 0, 0, 0],拼接后就是"6865000"。
  3. Array.from(buf)会把Uint8Array转为普通数组,普通数组的map不会做类型转换,回调返回的字符串会被完整保留,因此得到正确的十六进制拼接结果"68656c6c6f"。

内容的提问来源于stack exchange,提问作者vokeio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 06:54:47