手把手带你写一个JavaScript类型判断小工具

      业务写了很多,依然不是前端大神,我相信这是很多‘入坑’前端开发同学的迷茫之处,个人觉得前端职业发展是有路径可寻的,前期写业务是一个积累过程,后期提炼总结,比如编程思想,父子类的原型继承,还是对象之间的关联委托,设计模式的熟悉和运用,这都是一个前端工程师成长为高级工程师的必经之路,而这条道路是需要我们耐住性子,请相信,生活早晚会回报我们的努力。

      话不多说,进入我们今天的主题,JavaScript中判断一个数据的类型有多种方式:typeof、instanceof、constructor、Object.prototype.toString.call,一般判断简单的数据类型我们会使用typeof,但是对于数组,正则类型的数据,typeof是无能为力的,instanceof一般用于判断对象的继承关系,今天我们主要说的是Object.prototype.toString.call这个方法。

      1.判断类型      

我们可以写一个isType的方法来判断数据的类型,传入两个参数,第一个是需要判断的数据,第二个是数据类型。

前置知识:各个类型通过Object.prototype.toString.call方法后得到的结果

console.log(Object.prototype.toString.call('hello')) //[object String]
console.log(Object.prototype.toString.call(34)) //[object Number]
console.log(Object.prototype.toString.call(true))// [object Boolean]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(function f() {})) // [object Function]

下面我们就开始撸代码了:
function isType(content,type){
    //这里我们通过正则匹配去掉'[object ]',只留下类型
    let t = Object.prototype.toString.call(content).replace(/\[object\s|\]/g,'');
    //将得到的t与传入的type进行比较,返回结果,结果为Boolean类型
    return t === type;
}
//执行函数并将结果返回给res,打印res
let res = isType('hello','String')
console.log(res);//true复制代码

是不是非常简单,对自己又充满信心了,不过如此嘛!!确实很简单,来,继续,一点点深入~~

通过上面的一个函数我们就可以很容易的判断一个JavaScript数据的类型,但是我们在使用的时候是这个样子的:

let res1 = isType('hello','String');
let res2 = isType(123,'Number');
let res3 = isType(true,'Boolean');
复制代码

我们每次在使用的时候都是手动传入类型,很有可能手一抖,就传错类型了,本来'String',我们传入了'Strings',是不是很坑爹呀~~

一般的库或者插件不会这样去让我们使用,一般会这么使用utils.isString('hello'),我们只需要传入我们的数据就可以了,插件会提供相应的判断方法,比如

utils.isString('hello');
utils.isNumber(123);
utils.isBoolean(true);复制代码

这里我们需要批量化生产函数,就需要用到下面的一个函数返回一个函数,也就是所谓的闭包,也被叫做高阶函数,不要那些高大上,我们程序员都是接地气的~~,初学者对于闭包理解起来比较困难,不着急,随着你的深入,都会明白的~~~

      2.一个函数返回一个函数

接下来我们对上面的isType函数进行改造,

let isNumber = isType('Number');
let isString = isType('String');
let isBoolean = isType('Boolean');
isNumber(12);
isString('hello');
isBoolean(true)复制代码

通过执行isType(),我们可以得到想要的函数,说明在isType内部,我么返回了一个函数,返回的这个函数对于外层函数 (也就是isType) 的参数进行了引用,JavaScript的垃圾回收机制是不会回收被引用的数据的,所以type被保留在了返回函数的内部,这就是闭包机制。

function isType(type) {
    return function(content) {
        let t = Object.prototype.toString.call(content).replace(/\[object\s|\]/g,'');
        return t === type;
    }
}复制代码

通过执行isType,我们得到了对内部函数的引用。

isNumber(12);
isString('hello');
isBoolean(true);复制代码

上面其实就是对isType内部函数的执行。

也不过如此嘛,说好的手把手带我们写一个判断类型插件呢!?

      3.属于我们自己的判断JavaScript类型插件

有些同学已经有启发了,我们可以这样操作

let type = ['String','Number','Function','Undefined','Boolean','Array'];
let utils = {};
type.forEach(item => {
    utils['is' + item] = isType(item);
})
复制代码

下面是console.log(utils)的结果


是不是很惊喜~~

我们可以利用ES6的模块化机制来封装这个方法,然后erport 出去供小伙伴使用,是不是很简单,也可以上传到npm,供广大开发者使用,是不是很有成就感。(估计这个难度的插件去你npm下载使用的人几乎没有,这里我们掌握怎么通过闭包去处理问题这个思想就行)下面是完整版utils.js

function isType(type) {
   return function(content) {
      let t = Object.prototype.toString.call(content).replace(/\[object\s|\]/g,'');
      return t === type;
   }
}

function createUtils(){
    let utils = {};
    let type = ['String','Number','Function','Undefined','Boolean','Array'];
    type.forEach(item => {
       utils['is' + item] = isType(item);
    })
    return utils;
}
let utils = createUtils();
export default{utils}复制代码

希望对你有所帮助,这条路还很长,慢慢来~~~

后续敬请期待算法与数据结构系列~~~~

如果你觉得对你又帮你,请点个赞,这是对原创者最大的写作分享动力~~~~


猜你喜欢

转载自juejin.im/post/5bc99d106fb9a05d0261299b