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