createMathOperation

Optimism is the faith that leads to achievement. Nothing can be done without hope and confidence.

— Helen Keller

本文为 《lodash 源码阅读》 系列文章,后续内容会在 github 中发布,欢迎 star,gitbook 同步更新。

依赖

import baseToNumber from './baseToNumber.js';
import baseToString from './baseToString.js';

源码

/**
 * 创建对两个值做数学运算的函数
 *
 * @private
 * @param {Function} operator 执行数学运算的函数
 * @param {number} [defaultValue] 默认返回值(未传值)
 * @returns {Function} 返回新的数学运算函数
 */
function createMathOperation(operator, defaultValue) {
  return (value, other) => {
    // 当两个数都未传递时
    if (value === undefined && other === undefined) {
      return defaultValue;
    }
    // 当第二个数未传递时
    if (value !== undefined && other === undefined) {
      return value;
    }
    // 当第一个数未传递时
    if (other !== undefined && value === undefined) {
      return other;
    }
    // 当传递的参数类型存在字符串时,将两个值都转换成字符串
    if (typeof value === 'string' || typeof other === 'string') {
      value = baseToString(value);
      other = baseToString(other);
    }
    // 否则将两个值转成数字
    else {
      value = baseToNumber(value);
      other = baseToNumber(other);
    }
    return operator(value, other);
  };
}

原理

思路

createMathOperation 是一个高阶函数,它接收 operator 函数参数,在内部封装了一个对接收参数做类型检测并转换的新函数,并将其返回。

undefined 检测

前三个 if 条件,对值为 undefined 做了检测,并返回对应值。 这部分的判断条件为 value === undefined 而没有使用 value === void 0,这是为什么呢?难道 lodash 作者不担心 undefined 变量被全局修改吗?相关原因可以查看 lodash 源码阅读 —— isUndefined

类型转换

在接下来的处理中,新函数判断传递的参数中是否存在字符串,存在时则将两个变量进行 baseToString 转换进行数学运算,否则进行 baseToNumber 转换,这样做是为什么呢? 在 《Javascript 高级程序设计(第三版)》 第三章中介绍 加性操作符-加法 时,说明了这段规则:

如果有一个操作数是字符串,那么就要应用如下规则:

  • 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;

  • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来。

若存在一个操作数是字符串类型,javascript 会将两个操作数转化为 String 后进行操作,而 baseToString 则是对原生 toString 的优化。而在非加法的运算操作中,程序会将 非数值类型 进行 Number 化,所以提前将操作数 String 化,不会影响最终的运行结果。同理,baseToNumber 则是对 Number() 方法的优化。

相关链接

参考

  • 《Javascript 高级程序设计(第三版)》

Last updated

Was this helpful?