话不多说,进入我们今天的主题,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}
希望对你有所帮助,这条路还很长,慢慢来~~~
后续敬请期待算法与数据结构系列~~~~
如果你觉得对你又帮你,请点个赞,这是对原创者最大的写作分享动力~~~~