一文搞定JavaScript的数据类型检测

男娘i 2022-10-14 01:21 282阅读 0赞

文章目录

    1. typeof
    1. instanceof
    1. constructor
    1. Object.prototype.toString.call()
  • 参考

面试题中经常会考js数据类型检测,我们今天一文彻底搞定这个问题。

1. typeof

对于原始数据类型,我们可以使用typeof()函数来判断他的数据类型:

  1. console.log(typeof "");
  2. console.log(typeof 1);
  3. console.log(typeof true);
  4. console.log(typeof null);
  5. console.log(typeof undefined);
  6. console.log(typeof []);
  7. console.log(typeof function(){ });
  8. console.log(typeof { });

看看控制台输出什么

2c64a6bcd5f6cf484a6e7699d4124b36.png

可以看到,typeof对于基本数据类型判断是没有问题的,但是遇到引用数据类型(如:Array)是不起作用的。

typeof null

  1. // JavaScript 诞生以来便如此
  2. typeof null === 'object';

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 “object”。

曾有一个 ECMAScript 的修复提案(通过选择性加入的方式),但被拒绝了。该提案会导致 typeof null === ‘null’。

2. instanceof

typeof()函数对于原始类型的判断还差强人意,但他是没法用来区分引用数据类型的,因为所有的引用数据类型都会返回”object”。于是javascript引入了java中使用的instanceof,用来判断一个变量是否是某个对象的实例,所以对于引用类型我们使用instanceof来进行类型判断。

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

  1. console.log("1" instanceof String);
  2. console.log(1 instanceof Number);
  3. console.log(true instanceof Boolean);
  4. // console.log(null instanceof Null);
  5. // console.log(undefined instanceof Undefined);
  6. console.log([] instanceof Array);
  7. console.log(function(){ } instanceof Function);
  8. console.log({ } instanceof Object);

暂且不考虑null和undefined(这两个比较特殊),看看控制台输出什么。

fd1608f97d913a4178d9b136bb7d85f1.png

可以看到前三个都是以对象字面量创建的基本数据类型,但是却不是所属类的实例,这个就有点怪了。后面三个是引用数据类型,可以得到正确的结果。如果我们通过new关键字去创建基本数据类型,你会发现,这时就会输出true,如下:

c2ed7a8c263da5a622b2a139bb6a3033.png

具体为什么会这样呢?我们看MDN的解释:

  1. var simpleStr = "This is a simple string";
  2. var newStr = new String("String created with constructor");
  3. simpleStr instanceof String; // 返回 false, 非对象实例,因此返回 false
  4. newStr instanceof String; // 返回 true

接下再来说说为什么null和undefined为什么比较特殊,实际上按理来说,null的所属类就是Null,undefined就是Undefined,但事实并非如此:控制台输出如下结果:

19ba713f0e85deacddad90ea34e2c426.png

浏览器压根不认识这两货,直接报错。在第一个例子你可能已经发现了,typeof null的结果是object,typeof undefined的结果是undefined

7b73ae25c91bf7d85ba1e07b6ec92072.png

尤其是null,其实这是js设计的一个败笔,早期准备更改null的类型为null,由于当时已经有大量网站使用了null,如果更改,将导致很多网站的逻辑出现漏洞问题,就没有更改过来,于是一直遗留到现在。具体为什么 typeof null = ‘object’,我们前文已经介绍过了,作为学习者,我们只需要记住就好。

3. constructor

在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用

就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的

如: (a instanceof Array) //a是否Array的实例?true or false

(a.constructor == Array) // a实例所对应的构造函数是否为Array? true or false

  1. console.log(("1").constructor === String);
  2. console.log((1).constructor === Number);
  3. console.log((true).constructor === Boolean);
  4. //console.log((null).constructor === Null);
  5. //console.log((undefined).constructor === Undefined);
  6. console.log(([]).constructor === Array);
  7. console.log((function() { }).constructor === Function);
  8. console.log(({ }).constructor === Object);

49b380b636f92a5633e6b34caaefec76.png

(这里依然抛开null和undefined)乍一看,constructor似乎完全可以应对基本数据类型和引用数据类型,都能检测出数据类型,事实上并不是如此,来看看为什么:

  1. function Fn(){ };
  2. Fn.prototype=new Array();
  3. var f=new Fn();
  4. console.log(f.constructor===Fn);
  5. console.log(f.constructor===Array);

7954038a101f80a7cf8b5b846484f03d.png

我声明了一个构造函数,并且把他的原型指向了Array的原型,所以这种情况下,constructor也显得力不从心了。

看到这里,是不是觉得绝望了。没关系,终极解决办法就是第四种办法,看过jQuery源码的人都知道,jQuery实际上就是采用这个方法进行数据类型检测的。

4. Object.prototype.toString.call()

  1. var a = Object.prototype.toString;
  2. console.log(a.call("aaa"));
  3. console.log(a.call(1));
  4. console.log(a.call(true));
  5. console.log(a.call(null));
  6. console.log(a.call(undefined));
  7. console.log(a.call([]));
  8. console.log(a.call(function() { }));
  9. console.log(a.call({ }));

36975986e82f43526cbfdc1046ef022e.png

可以看到,所有的数据类型,这个办法都可以判断出来。那就有人质疑了,假如我把他的原型改动一下呢?如你所愿,我们看一下:

69561947653c58bb46da3cfb171fe221.png

可以看到,依然可以得到正确的结果。

参考

  • js检测数据类型四种办法
  • javascript数据类型的判断
  • MDN

发表评论

表情:
评论列表 (有 0 条评论,282人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Scala

    第一节:概述 为什么学习Scala ? Apache Spark 是专为大规模数据快速实时处理的计算引擎/内存级大数据计算框架。Apache Spark 是由Sca