JavaScript中如何基于Uint8Array数值映射获取字符串数组
问题复现
运行以下代码会出现返回值不符合预期的情况:
new Uint8Array([1,2,3]).map((v,y)=>"0"+v+"0"+y) // 实际输出:Uint8Array(3) [ 100, 201, 46 ] // 预期输出:["0100","0201","0302"] new Uint8Array([1,2,3]).map((v,y)=>v+1) // 实际输出:Uint8Array(3) [ 2, 3, 4 ],和预期一致 [1, 2, 3].map(x => "0"+x); // 实际输出:["01", "02", "03"],和预期一致
原因说明
Uint8Array属于类型化数组,它自带的map方法返回值仍然是同类型的Uint8Array实例,只能存储0-255之间的整数值。如果回调返回非数值类型(比如字符串),会被强制转换为Uint8类型数值:比如字符串"0302"转数字是302,超过Uint8最大值255时会做302 % 256计算得到46,和实际运行结果一致,因此无法直接通过类型化数组原生的map方法得到字符串组成的普通数组。
解决方案
选择以下任意一种方法即可得到预期的普通字符串数组:
- 方案1:使用
Array.from一步完成类型转换+映射,不需要生成中间数组,写法简洁const result = Array.from(new Uint8Array([1,2,3]), (value, index) => `0${value}0${index}`) // 输出:["0100","0201","0302"] - 方案2:先将Uint8Array转为普通数组,再调用普通数组的map方法,符合日常数组操作习惯
// 用展开运算符转普通数组 const result1 = [...new Uint8Array([1,2,3])].map((value, index) => `0${value}0${index}`) // 也可以用Array.from先转再map const result2 = Array.from(new Uint8Array([1,2,3])).map((value, index) => `0${value}0${index}`) - 方案3:借用普通数组的map方法直接处理Uint8Array,兼容不支持展开运算符的老旧运行环境
const result = Array.prototype.map.call(new Uint8Array([1,2,3]), (value, index) => `0${value}0${index}`)
内容的提问来源于stack exchange,提问作者BogdanBiv
相关产品推荐
相关产品推荐

