🚀看完这个,你总该会JS的类型判断了吧!!!🎉

823 阅读5分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


数据类型

谈类型判断之前,还是先来回顾回顾js有哪些类型。

  • 基本数据类型:Undefined、Null、Boolean、Number、String,Symbol,BigInt(symbol和bigint是ES6新增)
  • 引用数据类型 :Object(有包含了Array,function、Date、RegExp等)

了解了数据类型之后,我们再来看看有哪些方法来判断。


判断方法

1、typeof

typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等,来我们上代码看看具体情况。

typeof'';// string 有效
typeof 1;// number 有效
typeof Symbol();// symbol 有效
typeof true;//boolean 有效
typeof undefined;//undefined 有效
typeof null;//object 无效
typeof [] ;//object 无效
typeof new Function();// function 有效
typeof new Date();//object 无效
typeof new RegExp();//object 无效

分析:可以发现,typeof并不能完全准确的判断出数据类型。

  • 基本类型中,null不能被判断出来,会返回Object
  • 引用类型中,只有function能准确判断,其他的应用类型如Array,Date等都不行。

由此看来,typeof更加适用于基本类型的判断,并且如果需求上有对null有要求,更要做好对null的特判。

2、instanceof

这个方法用来判断一个对象是否是某个类的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。

let bool = true;
let num = 1;
let str = 'abc';
let  und= undefined;
let nul = null;
let arr = [1,2,3,4];
let obj = {name:'xiaoming',age:22};
let fun = function(){console.log('hello')};
let s1 = Symbol();
​
console.log(bool instanceof Boolean);// false
console.log(num instanceof Number);// false
console.log(str instanceof String);// false
console.log(und instanceof Object);// false
console.log(nul instanceof Object);// false
console.log(arr instanceof Array);// true
console.log(obj instanceof Object);// true
console.log(fun instanceof Function);// true
console.log(s1 instanceof Symbol);// false

分析:我们可以发现从结果中看出instanceof

  • 不能识别出基本的数据类型 number、boolean、string、undefined、unll、symbol。
  • 可以检测出引用类型,如array、object、function

所以说,instanceof适用于引用类型的判断。但在这里需要特别注意的是: instanceof 检测的是原型 ,也就是说他的判断实质上是通过原型链去查找,比如,A instanceof B,会去A的原型链上查找看是否有B,如果有就返回true,没有就沿着原型链往上找,直到顶。所以我们可以看出来这个能判断出亲属关系,但不一定能确定有多亲,如下实例

var arr = []
console.log(arr instanceof Array) //true
console.log(arr instanceof Object) //true
console.log(Array instanceof Object) //true

分析:很明显,arr是Array的实例,那为什么又是Object的实例,难道这个方法是错的?当然不是了,我们都知道Array是Object的一种实例对象,可以说,Array就是Object的儿子,而arr又是Array的儿子,有了这层继承关系,再加上instanceof是通过原型链去定位的,因此,instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型

那么又该怎么来准确判断是不是数组(Array)类型呢?别担心,ES5给我们提供了一个接口Array.isArray()来帮助我们判断

var arr = []
console.log(arr.isArray())
3、constructor

如果了解原型和原型链的话,对这个比较清楚。不了解也没有关系后续我会专门写一篇关于原型和原型链的文章。

回归正题。在JS中,当一个函数 F被定义时,JS引擎会为F添加 prototype 原型,然后再在 prototype上添加一个 constructor 属性,并让其指向 F 的引用。不了解原型链可能不太好理解。换句话说,每个实例对象(原型实例)都会有一个__proto__属性,在这个属性下面定义了一个constructor属性里面保存了实例对象的构造函数,构造函数的名称就是实例对象的原型(可以理解为他的父亲),以此可以来判断实例对象的原型

let bool = true;
let num = 1;
let str = 'abc';
let  und= undefined;
let nul = null;
let arr = [1,2,3,4];
let obj = {name:'xiaoming',age:22};
let fun = function(){console.log('hello')};
let s1 = Symbol();console.log(bool.constructor === Boolean);// trueconsole.log(num.constructor === Number);// true
console.log(str.constructor === String);// true
console.log(arr.constructor === Array);// true
console.log(obj.constructor === Object);// true
console.log(fun.constructor === Function);// true
console.log(s1.constructor === Symbol);//true

但是要注意:null 和 undefined 是无效的对象,对来undefined和null来说是不安全的,因为constructor的指向是可以被改变。因此他们是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。我被坑过,大家小心。

4、toString

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

let bool = true;
let num = 1;
let str = 'abc';
let  und= undefined;
let nul = null;
let arr = [1,2,3,4];
let obj = {name:'xiaoming',age:22};
let fun = function(){console.log('hello')};
let s1 = Symbol();
console.log(Object.prototype.toString.call(bool));//[object Boolean]
console.log(Object.prototype.toString.call(num));//[object Number]
console.log(Object.prototype.toString.call(str));//[object String]
console.log(Object.prototype.toString.call(und));//[object Undefined]
console.log(Object.prototype.toString.call(nul));//[object Null]
console.log(Object.prototype.toString.call(arr));//[object Array]
console.log(Object.prototype.toString.call(obj));//[object Object]
console.log(Object.prototype.toString.call(fun));//[object Function]
console.log(Object.prototype.toString.call(s1)); //[object Symbol]

分析:可能大家在好奇为什么要加上Object.prototype.toString.call,开头已经说toString是Object的原型方法,对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过call / apply改变this指向再来调用才能返回正确的类型信息。

此方法可以相对较全的判断js的数据类型。但具体用哪个方法还是要看具体场景下的具体需求,一般基本的类型可以选择typeof,引用类型可以使用instanceof。

\

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤

「欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章」。