Lodash源码阅读-toFinite

88 阅读2分钟

功能概述

toFinite 函数是一个强大的类型转换工具,它可以将各种类型的值转换为有限数值。不管你传入什么类型的值,它都会尽量将其转换为一个有限的数字,如果实在无法转换,就会返回 0。

源码实现

function toFinite(value) {
  if (!value) {
    return value === 0 ? value : 0;
  }
  value = toNumber(value);
  if (value === INFINITY || value === -INFINITY) {
    var sign = value < 0 ? -1 : 1;
    return sign * MAX_INTEGER;
  }
  return value === value ? value : 0;
}

var INFINITY = 1 / 0,
  MAX_SAFE_INTEGER = 9007199254740991,
  MAX_INTEGER = 1.7976931348623157e308,
  NAN = 0 / 0;

实现原理解析

整体思路

toFinite 函数采用了一种层层把关的策略,通过四个主要步骤来确保输出一个有限数值:

  1. 零值处理:处理假值(falsy)的情况
  2. 数值转换:将输入值转换为数字
  3. 无穷值处理:处理无穷大和无穷小
  4. NaN 处理:确保返回有效数字

让我们详细看看每个判断条件:

1. 零值处理

if (!value) {
  return value === 0 ? value : 0;
}

这一步主要处理所有的假值情况:

_.toFinite(0); // => 0
_.toFinite(""); // => 0
_.toFinite(null); // => 0
_.toFinite(false); // => 0

特别注意的是,它对 0 和 -0 进行了特殊处理,保留了它们的原始值:

_.toFinite(0); // => 0
_.toFinite(-0); // => -0

2. 数值转换

value = toNumber(value);

使用 toNumber 函数将输入值转换为数字:

_.toFinite("3.2"); // => 3.2
_.toFinite("0xff"); // => 255
_.toFinite(true); // => 1
_.toFinite([1]); // => 1
_.toFinite({
  valueOf: function () {
    return 5;
  },
}); // => 5

3. 无穷值处理

if (value === INFINITY || value === -INFINITY) {
  var sign = value < 0 ? -1 : 1;
  return sign * MAX_INTEGER;
}

当遇到无穷大或无穷小时,返回 JavaScript 能表示的最大或最小数:

_.toFinite(Infinity); // => 1.7976931348623157e+308
_.toFinite(-Infinity); // => -1.7976931348623157e+308

4. NaN 处理

return value === value ? value : 0;

最后一步处理 NaN 的情况。由于 NaN 是唯一一个不等于自身的值,这个判断可以巧妙地检测出 NaN:

_.toFinite(NaN); // => 0
_.toFinite("abc"); // => 0 (因为 'abc' 转换为数字后是 NaN)

总结

toFinite 函数通过巧妙的判断和转换,能够将各种类型的输入值转换为有限数值。它的实现考虑了各种边界情况,包括零值、无穷值和 NaN 等特殊情况,使其在实际应用中具有很强的健壮性。