精准判断数据类型的方法--Object.prototype.toString.call()

104 阅读2分钟

前言

常见的判断数据类型的方法主要有typeof,instanceof,但这两种方法都有缺陷。

typeof :

object,arr,null不能分辨,都返回object

instanceof :

Number,Boolean,String基本数据类型不能判断,都返回false

undefined,null无原型链,不能使用instanceof

最精准的方法为Object.prototype.toString.call(),但不易识记,因此本文主要介绍其原理,辅助理解记忆。

Object.prototype.toString.call()原理

  • 首先Object.prototype有一个内置方法为toString,其返回格式为[object xxxx],其中xxxx表示调用这个方法的数据的数据类型.
       const JudgeType = Object.prototype.toString
       console.log(JudgeType.call(1),'数字')              //[object Number] 数字
       console.log(JudgeType.call('字符串'),'字符串')      //[object String] 字符串
       console.log(JudgeType.call(true),'布尔')           //[object Boolean] 布尔
       console.log(JudgeType.call(undefined),undefined)   //[object Undefined] undefined
       console.log(JudgeType.call(null),null)             //[object Null] null
       console.log(JudgeType.call([]),'数组')             //[object Array] 数组
       console.log(JudgeType.call({}),'对象')             //[object Object] 对象
       console.log(JudgeType.call(function(){}),'函数')   //[object Function] 函数
       //ES6新增
       console.log(JudgeType.call(Symbol()),'symbol')     //[object Symbol] symbol
       console.log(JudgeType.call( new Set()),'set')     //[object Set] set
       console.log(JudgeType.call( new Map()),'map')     //[object Map] map
  • 同时,js内部重写了一些数据类型的toString的方法,例如Function.toString(),其返回值为该函数的字符串格式.
       const test = function(){
        console.log(111)
       }
       console.log(test.toString()); //"function(){console.log(111)}"
  • 因此,如果我们直接使用这些数据类型的toString方法时,根据原型链的原理会寻找最近一级拥有toString方法的原型对象,这样会直接寻找到其构造函数原型对象上的toString方法,而无法使用 Object.prototypetoString方法.

  • 想要使用 Object.prototype.toString有两种方法(以函数为例):

1.删除该数据类型的构造函数的原型对象上的toString方法

delete Function.prototype.toString

2.改变Object.prototype.toStringthis指向

Object.prototype.toString.call(function(){})

显然方法1我们并不常用,因此可以采用方法2,即使用call直接将this指向改为需要判断的数据

尾声

如果发现本文有错误,还请在评论区指正;如果看官觉得本文对你有帮助,麻烦点一个小小的赞