问题描述
从数据库(Mongodb)中取的身份证号是lang类型,需要转换成字符串类型。拿到这个需求的时候没有多想,上来就是toString
,+''
,类似:
var idCardNo = 110105199805241789;
var idString = idCardNo + '';
// 或者 var idString = idCardNo.toString();
console.log(idString,typeof(idString));
// 110105199805241800 string
输出并不是身份证号变成了字符串,而是:'110105199805241800'
,结尾789
变成了800
,什么鬼?
这不是我想要的结果……
解释
number能表示的范围
Javascript的基本数据类型number
是双精度浮点数,它可以表示的最大安全范围是±9007199254740991
,也就是±253-1,用Number.MAX_SAFE_INTEGER
和Number.MIN_SAFE_INTEGER
可以查看对应的数字。
const max = Number.MAX_SAFE_INTEGER;
console.log(max); //9007199254740991
const min= Number.MIN_SAFE_INTEGER;
console.log(min); //-9007199254740991
因此,当对安全整数范围外的整数进行计算时,可能会失去精度,出现精度损失,会进行"四舍五入"(当然不是真的四舍五入)。
var idCardNo = 110105199805241789;
var idString = idCardNo.toString() //110105199805241800
var res = idString - idCardNo;
console.log(res); //0
console.log(idString == idCardNo); //true
console.log(110105199805241800 === 110105199805241789); //true
//也就是说在Number的精度下,110105199805241800 = 110105199805241789
BigInt
BigInt
是Javascript的一种内置对象,是一个新的数字基本类型,可以用任意精度表示整数。
number
转BigInt
的方法有两种:
- 在数字后面加
n
即可
var big = 12345n;
typeof(big); //"bigint"
- 用
BigInt(number)
函数
var num = 12345;
var bigNum = BigInt(num);
typeof(bigNum); //"bigint"
注:chrome67+ 支持BigInt,低版本的浏览器可能不支持。
身份证号正确的转字符串方法
先把身份证号转为BigInt类型,再转字符串即可:
var idCardNo = 110105199805241789;
var bigIdCard = BigInt(idCardNo);
var idString = bigIdCard + '';
// 或者 var idString = bigIdCard.toString();
console.log(idString,typeof(idString));
// "110105199805241789" string
over,成功
补充知识
- BigInt中没有
±0
,只有一个0
- BigInt不能用于
Math
对象中的方法 - 不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。
+
、*
、-
、**
、%
可以和BigInt一起使用。除>>>
(无符号右移)之外的 位操作 也可以支持。因为 BigInt 都是有符号的,>>>
(无符号右移)不能用于 BigInt。- BigInt与Number不是严格相等的
1n === 1; //false
1n == 1; //true
- 当作为 key 时,值会被转换为字符串,而 BigInt 转字符串时是没有后缀 n 的,因此
list[1n]
与list[1]
等价,都是取的数组下标1(下标范围超253-1时例外)。