JS数字转二进制或十六进制字符串怎么写?
详细解析在JavaScript中如何将数字转换为二进制或十六进制字符串。涵盖Number.prototype.toString基础语法、字面量直接调用的语法陷阱、固定位宽补零格式化、负数32位无符号补码处理以及超大整数BigInt的转换方案。
toString(radix) 方法,并将目标进制(基数)作为参数传入:转二进制传入 2(即 num.toString(2)),转十六进制传入 16(即 num.toString(16))。在实际工程中,结合 padStart 实现固定位宽对齐补零、利用无符号右移运算符 >>> 0 解析负数补码,以及使用 BigInt 突破安全整数边界,便能完整覆盖全部应用场景。
一、基础写法:Number.prototype.toString(radix)
JavaScript 的 Number 原型对象提供了内置方法 toString([radix])。该方法接收一个介于 2 到 36 之间的整数参数 radix,表示基数(进制数)。如果省略参数,默认按照十进制输出。
1. 转为二进制字符串
将 radix 设置为 2,返回由 '0' 和 '1' 组成的字符串:
const decimalNum = 42;
const binaryStr = decimalNum.toString(2);
console.log(binaryStr);
// 示例输出: "101010"
2. 转为十六进制字符串
将 radix 设置为 16,返回由数字 0-9 与小写字母 a-f 组成的十六进制字符串。如果业务需要大写字母表示(例如某些硬件协议或色彩代码),可直接链式调用 toUpperCase():
const decimalNum = 255;
const hexLower = decimalNum.toString(16);
const hexUpper = decimalNum.toString(16).toUpperCase();
console.log(hexLower); // 示例输出: "ff"
console.log(hexUpper); // 示例输出: "FF"
二、语法陷阱:为什么字面量直接调用会报错?
许多初学者直接在数字字面量后写点调用方法时,会遭遇语法解析错误:
// 错误示例:会直接抛出 SyntaxError
255.toString(16); // SyntaxError: Invalid or unexpected token
原因解释:JavaScript 词法分析器在扫描到数字后的第一个点号 . 时,会优先将其解析为浮点数的小数点(例如 255.0)。紧随其后的字母 t 无法组成合法的浮点数字符序列,词法分析便在此时崩溃并抛出异常。
规避该词法冲突有以下四种合规写法:
- 使用分组括号包裹数值(最推荐):
(255).toString(16)。括号强制将255作为一个完整表达式求值,括号外的点号被正确识别为属性访问器。 - 双点语法:
255..toString(16)。第一个点号被词法分析器判定为浮点数的小数点,第二个点号则顺理成章地被识别为调用属性/方法。 - 添加空格隔离:
255 .toString(16)。数字与点号之间的空格强制截断了数字 Token 的扫描。 - 将数值赋给变量后调用:
const n = 255; n.toString(16);。变量名标识符绝不会被误认为数字,这是业务代码中最自然的形式。
三、工程格式化:固定位宽对齐与前缀修饰
在处理网络协议、加密哈希、二进制掩码或十六进制颜色代码时,系统往往要求固定位宽(例如单字节必须是 8 位二进制、2 位十六进制,缺失的高位需要补 0)。
原生 toString() 返回的是紧凑字符串(不会自动补充前导零)。例如 (5).toString(2) 只返回 "101"。为了将其格式化为标准的单字节 8 位表示,可结合 ES2017 引入的 String.prototype.padStart():
// 1. 二进制单字节对齐(固定 8 位宽,不足前置补 0)
const byteVal = 5;
const binFormatted = byteVal.toString(2).padStart(8, '0');
console.log(binFormatted); // 示例输出: "00000101"
// 2. 十六进制单字节对齐(固定 2 位宽)
const hexByte = byteVal.toString(16).padStart(2, '0');
console.log(hexByte); // 示例输出: "05"
// 3. 组装标准十六进制颜色代码 (#RRGGBB)
const r = 255, g = 10, b = 128;
const colorHex = '#' + [r, g, b]
.map(c => c.toString(16).padStart(2, '0'))
.join('');
console.log(colorHex); // 示例输出: "#ff0a80"
// 4. 添加规范前缀(0b 或 0x)
const withPrefixBin = '0b' + byteVal.toString(2).padStart(8, '0');
const withPrefixHex = '0x' + byteVal.toString(16).padStart(2, '0');
console.log(withPrefixBin); // 示例输出: "0b00000101"
console.log(withPrefixHex); // 示例输出: "0x05"
padStart(targetLength, padString) 当源字符串自身长度已经大于或等于 targetLength 时,会完整保留原始字符串,绝不会发生截断现有数值位的情况。
四、进阶处理:负数转换与 32 位无符号补码
当对负数直接调用 toString(2) 或 toString(16) 时,JavaScript 的默认行为是在绝对值的转换结果前简单拼接负号 "-":
const neg = -10;
console.log(neg.toString(2)); // 示例输出: "-1010"
console.log(neg.toString(16)); // 示例输出: "-a"
这种表现形式属于人类视角的代数符号表示。但在计算机硬件底层、数据报文解析或位掩码运算中,负数是以补码(Two's Complement)形式存储的。如果要获取其在内存中真实的 32 位补码二进制或十六进制字符串,需要配合 JavaScript 的无符号右移运算符 >>> 0。
运作原理:位运算符 >>> 会强制将操作数转换为 32 位无符号整数(Uint32)。移动 0 位不会改变位数据,但会使得底层负数补码位模式被直接解释为一个正的无符号整数,从而能够生成完整的补码字符串:
const neg = -10;
// 获取 -10 的 32 位二进制补码字符串
const binTwosComp = (neg >>> 0).toString(2);
console.log(binTwosComp);
// 示例输出: "11111111111111111111111111110110"
// 获取 -10 的 32 位十六进制补码字符串
const hexTwosComp = (neg >>> 0).toString(16);
console.log(hexTwosComp);
// 示例输出: "fffffff6"
五、大数场景:突破 2^53 - 1 边界的 BigInt 转换
JavaScript 中普通的 Number 类型遵循 IEEE 754 双精度浮点标准,能够精确表示的安全整数上限为 Number.MAX_SAFE_INTEGER(即 2^53 - 1 = 9007199254740991)。一旦数值超过此范围,普通的 Number 运算与转换会丢失最低有效位精度。
对于高精度时间戳、雪花 ID(Snowflake ID)、密码学散列或大整数计算,必须使用 BigInt 类型。BigInt.prototype.toString(radix) 同样完整支持 radix = 2 与 radix = 16:
// 超过安全整数范围的大数值
const hugeNum = 9007199254740995n; // 字面量加 n 或 BigInt("9007199254740995")
// 大整数转二进制
const hugeBin = hugeNum.toString(2);
console.log(hugeBin);
// 示例输出: "10000000000000000000000000000000000000000000000000011"
// 大整数转十六进制
const hugeHex = hugeNum.toString(16);
console.log(hugeHex);
// 示例输出: "20000000000003"
BigInt 不支持无符号右移运算符 >>>。如果需要对超大负数进行补码计算,必须根据业务预定的字节宽度(如 64 位或 128 位),使用掩码运算手动计算补码(例如 (BigInt.asUintN(64, -10n)).toString(16))。
六、工程速查与技术决策拓扑
为了在实际开发中快速选用恰当的转换语法,下表总结了各种常见业务场景的推荐实现范式:
| 业务场景 | 典型目标格式 | 标准推荐代码 | 示例结果 |
|---|---|---|---|
| 常规正整数转二进制 | 紧凑二进制字符串 | (num).toString(2) |
(10) => "1010" |
| 网络协议/字节流查看 | 8位对齐二进制 (1 Byte) | (num).toString(2).padStart(8, '0') |
(10) => "00001010" |
| CSS/十六进制色彩拼接 | 2位对齐十六进制 | (num).toString(16).padStart(2, '0') |
(10) => "0a" |
| 协议大写十六进制 | 大写十六进制字符串 | (num).toString(16).toUpperCase() |
(255) => "FF" |
| 负数机器补码转换 | 32位无符号补码 | (num >>> 0).toString(2) / (16) |
(-1) => "ffffffff" |
| 超长数值/ID转换 | 高精度进制字符串 | BigInt(val).toString(2) / (16) |
精确转换无精度损失 |
综上所述,JavaScript 数字转二进制或十六进制字符串的核心方法是 num.toString(radix)。在实际业务中,记住字面量需要加括号 (val).toString(...) 以避免词法错误;需要格式化显示时使用 padStart;需要计算机底层位视角时借助 >>> 0 计算补码;而面对超安全整数的大数时使用 BigInt,即可稳健应对所有进制转换需求。
WebStorm内置JS代码格式化功能怎么用
2026-11-05 10:10:47
在线JS代码格式化与混淆压缩工具推荐及使用指南
2026-11-03 20:31:53
CodePen、JSFiddle与RunJS对比:哪款在线JavaScript编辑器更好用
2026-11-03 18:52:45
无需安装环境,5款主流JavaScript在线运行工具推荐
2026-11-03 18:23:26
JS怎么将地址栏查询字符串转换为JSON对象
2026-11-03 18:10:29
相关标签:








