curry 化函数的应用----数据类型判断

195 阅读1分钟

前言

不想或者没有引用 第三方依赖(lodash)做类型判断的时候,项目的里到处充斥typeof 或者Object.prototype.toString.call,Array.isArray...因为类型判断的使用很频繁,就做一个优化, 于是有了今天这份总结

image.png

类型判断的方法

  1. typeof
    console.log(typeof a);    //'undefined'
    console.log(typeof(true));  //'boolean'
    console.log(typeof '123');  //'string'
    console.log(typeof 123);   //'number'
    console.log(typeof NaN);   //'number'
    console.log(typeof null);  //'object'    
    let  fn = function(){};
    console.log(typeof(fn));  //'function'
    console.log(typeof(class c{}));  //'function'
    console.log(typeof []) //"object"

不足:null 和[]的返回都不是 我想要的

  1. Object.prototype.toString.call
    console.log(Object.prototype.toString.call(true));  //"[object String]"
    console.log(Object.prototype.toString.call('123') );  //"[object String]"
    console.log(Object.prototype.toString.call(123));   //"[object Number]"
    console.log(Object.prototype.toString.call(NaN) );   //"[object Number]"
    console.log(Object.prototype.toString.call(null));  //"[object Null]"
    let  fn = function(){};
    console.log(Object.prototype.toString.call(fn));  //"[object Function]"
    console.log(Object.prototype.toString.call(class c{}));  //"[object Function]"
    console.log(Object.prototype.toString.call([]));  //"[object Array]"

结果:都正确返回了我想要的结果 ,不足的一点这个方法无法判断实例类型

  1. 判断实例类型还是老老实实用instanceof

类型判断函数的封装

经过上面的实践对比Object.prototype.toString.call 还是靠谱的

基础版本思路:将类型和值做参数 返回一个Object.prototype.toString.call做类型判断

function isType(typing,val) {
    return Object.prototype.toString.call(val) === `[object ${typing}]`;
}
console.log(isType('String',27))//false
console.log(isType('String',’zoe‘))//true
//其他 嗯 。。。。不想试了

升级版本思路:curry包装isType,可以支持单个参数调用

// 实现一个通用的柯里化函数,可以自动的将一个函数转化成多次传递参数
const curring = (fn: Function) => {
  const exec = (sumArgs: any[]) => {
    //如果当前传入的参数个数小于函数参数的个数,需要返回一个新的函数,并且保留当前函数传入的参数 运用递归
    return sumArgs.length >= fn.length
      ? fn(...sumArgs)
      : (...args: any[]) => exec([...sumArgs, ...args]);
  };
  return exec([]); //用于收集每次执行时计入的参数,第一次默认为空
};

同时调整下我们的isType函数

function isType(typing: string) {
  //这里利用高阶函数 来保存参数(高阶函数其实就是一种闭包 这是我自己的理解 ,如果我说错了 你们可以指出,相互学习)
  return function (val: unknown) {
    return Object.prototype.toString.call(val) === `[object ${typing}]`;
  };
}

最后 单独export 对应的类型判断方法

export const isString = curring(isType)("String");
export const isNumber = curring(isType)("Number");
export const isArray = curring(isType)("Array");
export const isFunction = curring(isType)("Function");
export const isObject = curring(isType)("Object");

结果测试

console.log('123 isNumber',isNumber(123))
console.log("[] isArray", isArray([]));
console.log('`123` isNumber',isNumber('123'))
console.log("123 isArray", isArray(123));

测试工具:runcode image.png

最后

最后如果觉得本文有帮助 记得点赞三连哦 十分感谢