lizhongzhen11 / lizz-blog

前端学习
80 stars 6 forks source link

重学js —— 全局对象:函数属性(parseFloat/parseInt) #102

Open lizhongzhen11 opened 4 years ago

lizhongzhen11 commented 4 years ago

全局对象:函数属性(parseFloat/parseInt)

parseFloat ( string )

// 示例来源于MDN,加了点补充
parseFloat(3.14); // 3.14
parseFloat('3.14'); // 3.14
parseFloat(9n); // 9
parseFloat('314e-2'); // 3.14
parseFloat('0.0314E+2'); // 3.14
parseFloat('3.14some non-digit characters'); // 3.14
parseFloat('3.14.2.6'); // 3.14
parseFloat('0.0314E+2.5-9'); // 3.14
parseFloat(''); // NaN
parseFloat(undefined); // NaN
parseFloat(null); // NaN
parseFloat(true); // NaN
parseFloat(false); // NaN
parseFloat([]); // NaN
parseFloat({}); // NaN
parseFloat({ toString: function() { return "3.14" } }); // 3.14

// 太大失去精度时的表现
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.MAX_SAFE_INTEGER + 4 // 9007199254740996
parseFloat('9007199254740995') // 9007199254740996
  1. 定义 inputString? ToString(string)
  2. 定义 trimmedString! TrimString(inputString, start)
  3. 如果 trimmedStringtrimmedString 的任何前缀都不满足 StrDecimalLiteral 的语法,返回 NaN
  4. 定义 numberStringtrimmedString 的最长前缀,可能是 trimmedString 自己,满足 StrDecimalLiteral 的语法
  5. 定义 mathFloatnumberStringMV (数学值)
  6. 如果 mathFloat = 0R
    1. 如果 trimmedString 的第一个码元是 0x002D(减号),返回 -0
    2. 返回 +0
  7. 返回 mathFloatNumber 类型值

注意:parseFloat 只能将字符串的开头部分解释为 Number 值;它会忽略无法解释为十进制文字符号的任何码元,并且不会给出任何此类码元被忽略的指示。

parseInt ( string, radix )

// 来源于MDN + 补充
parseInt(0); // 0
parseInt(-0, 10); // 0
parseInt(0.9); // 0
parseInt(Infinity, 10); // NaN
0.99999999999999999 // 1
parseInt(0.99999999999999999); // 1
Number.MAX_SAFE_INTEGER // 9007199254740991
parseInt(Number.MAX_SAFE_INTEGER + 4, 10); // 9007199254740996
parseInt(9007199254740995n, 10); // 9007199254740996
parseInt(1n, 10); // 1

parseInt(); // NaN
parseInt(null); // NaN
parseInt(null, 10); // NaN
parseInt(undefined, 10); // NaN
parseInt(true); // NaN
parseInt(false); // NaN

parseInt([], 10); // NaN
parseInt({}, 10); // NaN
parseInt({toString() {return 1}}, 10); // 1

parseInt('', 10); // NaN
parseInt('7+6', 10) // 7
parseInt("15e2", 10); // 15

parseInt("015", 10); // 15
parseInt(015, 10); // 13
parseInt("0xF", 16); // 15
parseInt("F", 16); // 15
parseInt("1111", 2); // 15

parseInt(4.7 * 1e22, 10); // 4
parseInt(0.00000000000434, 10); // 4
  1. 定义 inputString? ToString(string)
  2. 定义 S! TrimString(inputString, start)
  3. 定义 sign 为 1
  4. 如果 S 不为空且 S 的第一个码元是 0x002D(减号),设置 sign 为 -1
  5. 如果 S 不为空且 S 的第一个码元是 0x002B(加号)或 0x002D(减号),从 S 中移除第一个码元
  6. 定义 R? ToInt32(radix)
  7. 定义 stripPrefixtrue
  8. 如果 R ≠ 0
    1. 如果 R < 2R > 36,返回 NaN
    2. 如果 R ≠ 16,设置 stripPrefixfalse
  9. 否则,
    1. 设置 R 为 10
  10. 如果 stripPrefixtrue
    1. 如果 S 的长度至少是 2 且 S 的前两个码元是 0x0X
      1. S 中移除前两个码元
      2. 设置 R 为 16
  11. 如果 S 包含的不是 R 进制的码元,定义 ZS 的子串,该子串由第一个此类码元 之前 的所有码元组成(例如 parseInt('7+6', 10)+6 会被忽略);否则,定义 ZS
  12. 如果 Z 为空,返回 NaN
  13. 定义 mathInt 为由 ZR 进制表示的 数学整数 值,将字母 A-Za-z 用于表示数值从10到35的数字。(但是,如果 R 是 10 且 Z 包含超过 20 个有效数,第20个数后面的每个有效数可能会被0替换,由具体实现决定;如果 R 不是 2,4,8,10,16,32mathInt 可能是由 ZR 进制表示依赖于具体实现的近似的 数学整数 值)
  14. 如果 mathInt = 0R
    1. 如果 sign = -1,返回 -0
    2. 返回 +0
  15. 定义 numbermathIntNumber 类型值
  16. 返回 sign × number

注意:parseInt 只能将字符串的开头部分解释为整数值;它会忽略不能被解释为整数值的部分。

经典面试题

[1, 2, 3].map(parseInt) 输出什么以及为什么?

[1, 2, 3].map(parseInt) // [1, NaN, NaN]

首先 parseInt 是函数,map 中接受的参数也是函数,所以上述代码可以转为:

[1, 2, 3].map((item, index) => {
  return parseInt(item, index)
})

这样一看,实际是对以下代码的求值:

parseInt(1, 0) // 1
parseInt(2, 1) // NaN
parseInt(3, 2) // NaN

根据上面 parseInt 算法规定,第二个参数 radix 如果等于 0,那么会采用十进制;如果不等于 0,则要看它是不是在 2 ~ 36 范围内。所以:

本篇结束