JavaScript数据类型判断方法总结

作者: 竹叶寨少主 | 来源:发表于2021-01-07 22:53 被阅读0次

1.typeOf

    该方法是开发中经常用到的判断数据类型的方法。其返回的数据类型包含以下7种:number、boolean、symbol、string、object、undefined、function。而我们知道JavaScript的基本数据类型有6种分别是 string、number、boolean、symbol、undefined、null。引用类型有object, Array, Date, Regexp,Function,Error。因此可以发现,该方法对于基本类型,除了null外,其余类型的判断都可以返回想要的结果。但null有自己的类型,typeof返回结果却是object。

console.log(typeof null) // object

    对于引用类型。该方法除了对function返回function类型外,其余均返回object。而引用类型中的 数组、日期、正则等也都有属于自己的具体类型,但typeof 对于这些类型的处理,只返回了处于其原型链最顶端的 object 类型。

console.log(typeof new Function()) // function
console.log(typeof new Error()) // object
console.log(typeof new RegExp()) // object

2.constructor属性

    我们知道构造函数的原型对象里面有一个 constructor 属性 ,它指回构造函数本身。利用这个属性也可以进行类型判断。当我们访问某个对象实例的constructor属性,js会沿着原型链向上查找。即会查找该实例的_proto_属性,通过该属性找到对象原型。而对象原型的constructor属性则指向该实例的构造函数。下面举例说明

function Person (){
    this.name = '小明'
 }
const person = new Person()

console.log(Person.prototype)
console.log(Person)
console.log(person)

    我们将原型,构造函数,对象实例分别打印出来看一下


constructor.jpg

可以发现,对象实例的_proto_指向对象原型,原型的constructor指回构造函数。下面使用该属性判断类型。

console.log(person.constructor === Person) // true
// 更多地
const arr = [1,2]
console.log(arr.constructor === Array) // true
console.log(new Error().constructor == Error) // true

注:null 和 undefined 是无效的对象,他们没有constructor属性。

3.instanceof

    该方法主要用于引用类型的判断,用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。该方法的判断原则是:沿着原型链检测,判断B是否在A的原型链上。下面用例子说明:

 const arr = [1,2]
 console.log(arr instanceof Array) // true
 console.log(arr instanceof Object) // true 

    Array,Objectd都在数组对象的原型链上,因此都返回true,这就反应了一个问题,就是该方法只能判断两者是否是实例与构造函数的关系,而不能判断其具体类型。
    我们知道该方法的实现原理就是判断B是否在A的原型链上,因此可以基于这条原则自己实现一个instanceof方法。

const myInstanceof = (left, right) => {
    // 基本数据类型都返回false
    if (typeof left !== 'object'&&typeof left !== 'function'||left === null) return false;
    let leftProto = left.__proto__ // 获取左边对象的原型
    let rightProto = right.prototype // 获取右边构造函数的原型
    // 沿着原型链向上查找
    while(leftProto)
    {
       if(leftProto === rightProto) return true
       // leftProto = leftProto.__proto__  不推荐使用__proto__ 属性
       leftProto = Object.getPrototypeOf(leftProto)
    }
    return false
  }
  const arr = [1,2]
  const foo = () => {
     console.log('xiaom')
  }
  console.log(myInstanceof(arr,Array)) // true
  console.log(myInstanceof(arr,Object)) // true
  console.log(myInstanceof(foo,Array)) // false
  console.log(myInstanceof(foo,Function)) // true
  console.log(myInstanceof(foo,Object)) // true

3.Object.prototype.toString

    该方法是判断类型最准确的方法。利用Object 的原型方法(Object.prototype.toString),调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object xxx] ,其中 xxx 就是对象的类型。对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来强制调用。 这里要说明一点,虽然所有的对象的原型链最终都指向了Object。按理说也都应该可以调用toString()方法,但实际上大多数对象都实现了自己的toString()方法。根据原型链的查找规则,对象调用toString时会首先访问自己实现的该方法。因此必须使用上述方法来让其强制执行Object原型上的toString()方法。

    Object.prototype.toString.call('str'),// [object String] 
    Object.prototype.toString.call(12),// [object Number]
    Object.prototype.toString.call([1,2]),//[object Array]
    Object.prototype.toString.call(false),//[object Boolean]
    Object.prototype.toString.call(undefined) ,// [object Undefined]
    Object.prototype.toString.call(null),// [object Null]
    Object.prototype.toString.call(new Function()) ,// [object Function]
    Object.prototype.toString.call(new Date()), // [object Date]
    Object.prototype.toString.call(new RegExp()), // [object RegExp]
    Object.prototype.toString.call(new Error()) // [object Error]

    可以看到,该方法虽然能准确判断类型,但返回结果不够直观。我们可以基于该方法结合正则表达式实现一个通用的类型判断函数。

function checkType(val) {
  return Object.prototype.toString
    .call(val)
    // 匹配object后的字符
    .replace(/^\[object (\S+)\]$/, "$1");
}
console.log(checkType(1)) // Number
console.log(checkType('2')) // String
console.log(checkType({name:'123'})) // Object
console.log(checkType([1,2,3]))  // Array
console.log(checkType(new RegExp())) // RegExp
console.log(checkType(()=>{console.log('123')})) // Function

参考:https://www.cnblogs.com/onepixel/p/5126046.html

相关文章

网友评论

    本文标题:JavaScript数据类型判断方法总结

    本文链接:https://www.haomeiwen.com/subject/lgisoktx.html