前言
不想或者没有引用 第三方依赖(lodash)做类型判断的时候,项目的里到处充斥typeof 或者Object.prototype.toString.call,Array.isArray...因为类型判断的使用很频繁,就做一个优化, 于是有了今天这份总结
类型判断的方法
- 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 和[]的返回都不是 我想要的
- 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]"
结果:都正确返回了我想要的结果 ,不足的一点这个方法无法判断实例类型
- 判断实例类型还是老老实实用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
最后
最后如果觉得本文有帮助 记得点赞三连哦 十分感谢