Number 数字相关的方法, 强制 、隐式类型转换 、进制之间转换
Number
注意:浮点数的运算,在计算机中是不够精确的
2e3 // 2 * 10³ => 2000
10E-2 // 10 * 10⁻² => 0.1
相关方法:
-
parseFloat(str)
把字符串转成 小数 或 整数- str 是字符串,如果不是字符串,浏览器会启动隐式转换默认将其转换为字符串,然后再进行 parseFloat 转换。如果是字符串,浏览器会从字符串左侧第一个字符开始查找,把找到的有效数字字符最后转为数字(如果一个都没找到,结构是NaN),直到遇到非有效数字字符则立即停止查找,不论后面是否还有有效数字字符,都不会继续往后面查找了。parseFloat 可以识别小数点。
-
parseInt(str, radix)
把字符串转成 整数- 参数是 字符串(规则同 parseFloat,不可识别小数点)
- radix 基数,告诉函数需要按哪种进制进行输出,默认十进制,范围是 2~36,如果不在这个范围内的,结果就是NaN
-
toFixed(num)
保留 num 位小数
参数是 数字 代表要保留的小数位数,会4舍5入 -
toLocaleString()
方法可把一个 Number 对象转换为本地格式的字符串。
返回值:数字的字符串表示,由实现决定,根据本地规范进行格式化,可能影响到小数点或千分位分隔符采用的标点符号。
问题:1. 浏览器兼容问题,2. 由于国际化标准的不同,不同环境输出的结果可能不一样。
const a = 1234567891000;
const b = 673439.4542;
console.log(a.toLocaleString()); // "1,234,567,891,000"
console.log(b.toLocaleString()); // "673,439.454" (小数部分四舍五入了)
Number(str)
字符串转数字
该方法会触发隐式类型转换,下文会详细提及。
数字与字符串相互转换
Number("123") // 123
123.toString() // "123"
实例应用:
强制类型转换
/*这两种方法转 空字符串,或者以字母开头(比如str="px12334") 输出结果都是 NaN */
let str = "100.456px";
console.log(parseFloat(str));//"100.456"
console.log(parseInt(str));//"100"
console.log(parseFloat(str).toFixed(2));//"100.46"
隐式类型转换
- Number() 方法会进行隐式类型转换,并最终输出数值类型为止。
规则:
// 字符串转数字:只要遇到非有效数字字符,结果就为NaN
Number("") // 0
Number("123") // 123
Number("123x") // NaN
// 其它基础数据类型转换结果
Number(true) // 1
Number(false) // 0
Number(null) // 0
Number(undefined) // NaN
// 会去除末尾的 n ,如果超过最大安全数字,就会采用科学计算法来进行显示
Number(10n) // 10
Number(100000000000000000000000000000000n) // 1e+32
/*
把对象转换为数字:
+ 先调用对象的 Symbol.toPrimitive 这个方法,如果不存在这个方法(结果是undefined),目前已知的只有`new Date()`有这个方法
+ 再调用对象的 valueOf 获取原始值,如果获取的不是原始值,
+ 再调用对象的 toString 把其变成字符串
+ 最后再把字符串基于 Number 转换为数字
*/
Number([]) // 0
Number([2]) // 2
Number([2, 3]) // NaN
Number({}) // NaN
对象内部的 Symbol.toPrimitive 的机制
xxx[Symbol.toPrimitive](hint){
// hint:'number' / 'string' / 'default'
// + number: 获取当前对象的数字类型的原始值
// + string:获取当前对象的字符串类型的原始值
// + default:根据操作获取数字或者字符串类型的原始值
重写对象内部的 Symbol.toPrimitive
let obj = {
name: 'liangyu',
age: 12,
[Symbol.toPrimitive](hint) {
let result;
switch (hint) {
case 'number':
result = 0;
break;
case 'string':
result = JSON.stringify(obj);
break;
default:
result = "";
}
return result;
}
};
console.log(Number(obj)); // hint: 'number' => 0
console.log(String(obj)); // hint: 'string' => {"name":"liangyu","age":12}
console.log(10 + obj); // hint: 'default' => "10"
console.log(10 - obj); // hint: 'number' => 10
- 不同类型的值进行 比较、运算 时也会产生隐式类型转换。详细的隐式类型转换
进制转换
parseInt(11, 2).toString(10) // 将二进制的11转成十进制,=> 3
parseInt(11, 10).toString(2) // 将十进制的11转成二进制,=> 1011
// 错误的二进制数,会输出NaN、1等不正确结果,需要控制输入的内容正确
// 同理可以将 任何进制的数转成任何进制
面试题
第一题:
let ary = [27.2, 0, '0013', '14px', 123];
ary = ary.map(parseInt)
console.log(ary);
解答:
先看看 map 做了什么
ary.map(function(item, index) { // 数组中有多少项,回调函数就被执行多少次
// item:当前迭代的项
// index:对应的索引
return "xxx"; // 原始数组不变,返回一个新数组,return 后面的值就是 新数组的每一项。
});
解题过程:
map每一次循环,回调函数都会执行一次parseInt(item, index)
回调函数第一次执行:parseInt(27.2, 0)
,parseInt 先将第一个参数 27.2 转成 "27.2",第二个参数 为非有效范围,进行布尔值转换,为 false,走默认的十进制。最后相当于执行了parseInt("27.2", 10)
=> 27
第二次执行:parseInt(0, 1)
,1不是有效的进制范围,=> NaN
第三次执行:parseInt('0013', 2)
,找到符合二进制的内容"001",把二进制的"001"转换为十进制0*2^2 + 0*2^1 + 1*2^0
=> 1
第四次执行:parseInt('14px', 3)
,找到符合三进制的内容"1",把三进制的"1"转换为十进制1*3^0
=> 1
第五次执行:parseInt(123, 4)
,把数字123转成"123",找到符合四进制的内容"123",把四进制的"123"转换为十进制1*4^2 + 2*4^1 + 3*4^0
=> 27
所以最后console.log(ary);
=> [27, NaN, 1, 1, 27]
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步