总结JS中判断数据类型的三种方式

JS现有数据类型

  在了解如何判断数据类型之前,我们首先要明确现在JavaScript中有几种数据类型。
  JavaScript中数据类型分为两类:基本数据类型引用数据类型基本数据类型包括:BooleanStringNumberNullUndefinedSymbol(ES6新增)BigInt(ES6新增)七种。引用数据类型包括:ObjectFunctionArrayDateRegExp 五种。一张图概括:

typeof

  typeof一般用于判断基础类型,它的具体用法是:

  typeof variable

  它会返回一个字符串,表示给定变量的类型。它能正确判断除了Null以外的六种基础类型。

  console.log(
    typeof true,        //'boolean'
    typeof 'hi',        //'string'
    typeof 100,         //'number'
    typeof undefined,   //'undefined'
    typeof Symbol(),    //'symbol'
    typeof 100n         //'bigint'
    typeof null         //'object'
   );

  从上面的代码可以看出,除了null以外,typeof都做出了正确的判断。却偏偏对null返回了object。

  造成这一异常的原因是:

 在JavaScript的最初版本中,使用的是32位系统,为了性能考虑使用低位存储了变量的类型信息,000开头代表是对象,然而null表示为全0,所以将它错误的判断为对象。
虽然现在的内部类型判断代码已经改变了,但这个Bug却一直流传下来。

对引用类型使用typeof时,对Function类型返回'function',对其他四种类型都返回'object'。

instancof

  instanceof通常用于判断一个对象到底是哪种引用类型,它的具体用法是:

    object instanceof constructor

  object是某个对象实例,constructor是某个引用类型的构造函数。如果object是给定引用类型(constructor)的实例,则返回true;否则返回false。

    [] instanceof Array;    //true
    {} instanceof Object;   //true
    new Date() instanceof Date;    //true

  原理instanceof是根据给定对象实例的原型链进行判断的,它会检测给定构造函数的prototype属性是否出现在这个实例的原型链上。如果出现了,则返回true;否则返回false。

  优点:根据原理也可以看出instanceof的优点,即instanceof不仅可以判断一个对象是否是某个原生引用类型的实例,也可以判断它是否是某个自定义类型的实例。

  缺陷:如果网页中包含多个框架,就存在多个不同的全局环境,不同的全局环境拥有不同的全局对象。由于ObjectArray等构造函数是window对象的属性,所以ObjectArray等构造函数也存在不同的版本。
  这导致如果将一个对象从一个全局环境传到另一个全局环境中,instanceof的判断会出错。比如:

   //test1.html
   <iframe src="./test2.html"></iframe>

  <script>
    Array === window.frames[0].Array;    //false
    let arr = [];
    arr instanceof Array;    //true
    arr instanceof window.frames[0].Array;    //false
  </script>

  可以看出,由于不同全局环境下,构造函数存在不同的版本。导致instanceof对同一个对象实例的判断出现了不同的结果。

Object.prototype.toString.call()

  Object.prototype.toString.call(anyValue);

  在任何值上调用Object原型对象上的toString方法,都会返回一个'[Object NativeConstructorName]'的字符串。这个NativeConstructorName是某个原生构造函数的名称,也就是该值的类型。

  Object.prototype.toString.call('');    //[object String]   
  Object.prototype.toString.call(100);    //[object Number]
  Object.prototype.toString.call([]);     //[object Array]
  Object.prototype.toString.call(new RegExp());    //[object RegExp]

  原理:每个类在内部都有一个[[Class]]属性,这个属性就指定了NativeConstructorName。因为原生数组的构造函数名与全局作用域无关,因此这个方法弥补了instanceof的缺陷。

  优点:它能正确地返回某个变量的类型,不管是基本类型还是引用类型。

  缺点:对于引用类型,它只能判断出原生引用类型的实例。对于任何自定义的类型,它永远返回'[object Object]'

参考文档:
instanceof - JavaScript | MDN
《JavaScript高级程序设计》

如果感到这篇文章对你有用,麻烦点个赞~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值