总结JavaScript类型判断的4种方法

123 阅读3分钟

JS类型判断

回答模板:

  1. js类型判断有4种方式,分别为typeof、instanceof、constructor、Object.prototype.toString.call
  2. typeof适用于基本数据类型的判断,也能判断Function
  3. instanceof适用于引用类型的判断,也能判断继承关系
  4. constructor无法判断null和undefined,constructor指向可以改变所以不安全
  5. Object.prototype.toString.call 适用于所有类型的判断
typeof✔️boolean、number、undefined、string、symbol、 function
✖️null、array、object
instanceof✔️array、object、function
✖️null、number、boolean、string、undefined、symbol
constructor✔️Boolean、Number、String,Symbol 、Array、Function、Object
✖️Undefined、Null
Object.prototype.toString.call✔️Boolean、Number、String、Symbol 、Array、Function、Object、 Undefined、Null
✖️

js中的数据类型

基本数据类型:Undefined、Null、Boolean、Number、String,Symbol
引用数据类型 :Object

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();

typeof

console.log(typeof bool); //boolean
console.log(typeof num);//number
console.log(typeof str);//string
console.log(typeof und);//undefined
console.log(typeof nul);//object
console.log(typeof arr);//object
console.log(typeof obj);//object
console.log(typeof fun);//function
console.log(typeof s1); //symbol

typeof可以识别出基本类型boolean,number,undefined,string,symbol以及function。但是不能识别null和引用数据类型,会把null、array、object统一归为object类型。

所以typeof可以用来识别一些基本类型。

instanceof

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、null、symbol。
但是可以检测出引用类型,如array、object、function,同时对于是使用new声明的类型,它还可以检测出多层继承关系。
其实也很好理解,js的继承都是采用原型链来继承的。比如objA instanceof A ,其实就是看objA的原型链上是否有A的原型,而A的原型上保留A的constructor属性。

所以instanceof一般用来检测对象类型,以及继承关系。

constructor

constructor 属性返回对象的构造函数。

var fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.constructor; // 返回 function Array() { [native code] }

console.log(bool.constructor === Boolean);// true
console.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没有construstor方法,因此constructor不能判断undefined和null。
但是他是不安全的,因为contructor的指向是可以被改变。

Object.prototype.toString.call

toString()未重写则直接调用,重写则需要用 call()Reflect.apply() 等方法来调用。

  • 对于 Object.prototype.toString.call(arg),若参数为 nullundefined,直接返回结果。
  • 若参数不为 nullundefined,则将参数转为对象,再作判断。
  • 转为对象后,取得该对象的 [Symbol.toStringTag] 属性值(可能会遍历原型链)作为 tag,如无该属性,或该属性值不为字符串类型,则依下表取得 tag, 然后返回 "[object " + tag + "]" 形式的字符串。(注意:tag应该为字符串类型,如"Boolean"、"Number")
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]

此方法可以相对较全的判断js的数据类型。

至于在项目中使用哪个判断,还是要看使用场景,具体的选择,一般基本的类型可以选择typeof,引用类型可以使用instanceof。