lodash源码解读——add

add.js
import createMathOperation from './.internal/createMathOperation.js' // 用于创建新的数学运算函数

/**
 * 将两个数字相加
 *
 * @since 3.4.0
 * @category Math
 * @param {number} augend 加法运算中的第一个数字
 * @param {number} addend 加法运算中的第二个数字
 * @returns {number} 返回总数。
 * @example
 *
 * add(6, 4)
 * // => 10
 */
const add = createMathOperation((augend, addend) => augend + addend, 0)
// 如果未提供 augend 或 addend 中的任何一个值,它们将默认为 0。

export default add
createMathOperation.js
import baseToNumber from './baseToNumber.js' // 用于将值转换为数字
import baseToString from './baseToString.js' // 用于将值转换为字符串

/**
 * 创建一个对两个值执行数学运算的函数
 *
 * @private
 * @param {Function} operator 执行操作的函数。
 * @param {number} [defaultValue] 用于“未定义”参数的值
 * @returns {Function} 返回新的数学运算函数。
 */
function createMathOperation(operator, defaultValue) {
  // 返回一个函数 value, other是调用 lodash 方法(例如_add)传入的参数
  return (value, other) => {
    // 如果第一个参数和第二个参数都没有定义 则返回默认值0
    if (value === undefined && other === undefined) {
      return defaultValue
    }
    // 如果第一个参数有值 第二个参数没有值 则返回第一个参数
    if (value !== undefined && other === undefined) {
      return value
    }
    // 如果第一个参数没有值 第二个参数有值 则返回第二个参数
    if (other !== undefined && value === undefined) {
      return other
    }
    // 如果第一个参数或者第二个参数为字符串(至少其中一个为字符串) 则将参数通过 baseToString 方法都转换为字符串
    if (typeof value === 'string' || typeof other === 'string') {
      value = baseToString(value)
      other = baseToString(other)
    } //如果两个参数都不是字符串 则将参数通过 baseToNumber 方法都转换为数字
    else {
      value = baseToNumber(value)
      other = baseToNumber(other)
    }
    return operator(value, other)
  }
}

export default createMathOperation
baseToNumber.js
import isSymbol from '../isSymbol.js'

/** 用作各种“Number”常量的引用。 */
const NAN = 0 / 0

/**
 * “toNumber”的基本实现,它不能确保二进制、十六进制或八进制字符串值的正确转换。
 *
 * @private
 * @param {*} value 要处理的值
 * @returns {number} 返回数字
 */
function baseToNumber(value) {
  // 如果是数字,直接返回
  if (typeof value === 'number') {
    return value
  }
  // 如果是 Symbol 类型,返回 NAN
  if (isSymbol(value)) {
    return NAN
  }
  // 将字符串通过 + 转换成数字
  return +value
}

export default baseToNumber
baseToString.js
import isSymbol from '../isSymbol.js'

const INFINITY = 1 / 0
// 表示正无穷大的常量,其值为 1/0。

const symbolToString = Symbol.prototype.toString
// 用于将 Symbol 值转换为字符串

/**
 * “toString”的基本实现,它不会将无效值转换为空字符串。
 *
 * @private
 * @param {*} value 要处理的值
 * @returns {string} 返回字符串。
 */
function baseToString(value) {
  // 如果是字符串 直接返回
  if (typeof value === 'string') {
    return value
  }
  // 如果 value 是数组,函数会递归地调用 baseToString 函数来处理数组的元素,并通过 map 方法将它们连接成一个字符串。
  if (Array.isArray(value)) {
    return `${value.map(baseToString)}`
  }
  // 如果 value 是 Symbol 值,调用 Symbol.prototype.toString.call方法进行转换 例如:Symbol('a') 的转换结果为 'Symbol(a)'
  if (isSymbol(value)) {
    return symbolToString ? symbolToString.call(value) : ''
  }
  // 如果以上情况都不满足,那么函数将使用 ${value} 将 value 转换为字符串。
  const result = `${value}`
  // 对字符串0 返回0 或者'-0'的处理
  return (result === '0' && (1 / value) === -INFINITY) ? '-0' : result
}

export default baseToString
isSymbol.js
import getTag from './.internal/getTag.js' // 用于获取值的内部标签(类型标识)

/**
 * 用于检查一个值是否为 Symbol 类型
 *
 * @since 4.0.0
 * @category Lang
 * @param {*} value 用于检查的值
 * @returns {boolean} 如果值是 Symbol 类型的返回 true,否则返回 false
 * @example
 *
 * isSymbol(Symbol.iterator)
 * // => true
 *
 * isSymbol('abc')
 * // => false
 */
function isSymbol(value) {
  const type = typeof value
  return type == 'symbol' || (type === 'object' && value != null && getTag(value) == '[object Symbol]')
}

export default isSymbol
getTag.js
const toString = Object.prototype.toString // 用于获取对象的字符串表示形式

/**
 * 用于获取值的 toStringTag
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
function getTag(value) {
  if (value == null) {
    return value === undefined ? '[object Undefined]' : '[object Null]'
  }
  return toString.call(value)
}

export default getTag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值