JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

我们在写封装的插件或者函数时,常常用到JS的数据类型判断,典型的案例就是深度拷贝函数用到数据类型判断,这个知识点在面试的时候也是经常考到的一个问题。今天在这里总结一下我个人遇到的可以判断数据类型的几种方式。如果有哪里写的不对还请指点一下小弟,以免文章误导他人。

1. typeof关键字

  1.  
    console.log(typeof 2); // number
  2.  
    console.log(typeof true); // boolean
  3.  
    console.log(typeof ‘str‘); // string
  4.  
    console.log(typeof []); // object []数组的数据类型在 typeof 中被解释为 object
  5.  
    console.log(typeof function(){}); // function
  6.  
    console.log(typeof {}); // object
  7.  
    console.log(typeof undefined); // undefined
  8.  
    console.log(typeof null); // object null 的数据类型被 typeof 解释为 object

结果如下图显示,空数组 和 null被 typeof 解释为 object 类型,有的人可能会认为 typeof 关键字对数组 和 null 的类型判断是错误的,其实typeof对于数组 和 null 的类型判断是正确的,只不过不够精准而已。

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

其他(数字Number,布尔值Boolean,字符串String,函数Function,对象Object,Undefined)这一些数据类型在typeof 下都被精准的解释,只有数组和null的数据类型不够精准。那么如何才能获取到 数组 和 null 的精准数据类型。这就用到下面这种方法。

2. instanceof关键字

undefined 和 null 在这里的表现有点异于寻常数据,我们先注释掉

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

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

以上结果显示,直接的字面量值判断数据类型,只有引用数据类型(Array,Function,Object)被精准判断,其他(数值Number,布尔值Boolean,字符串String)字面值不能被instanceof精准判断。我们来看一下 instanceof 在MDN中的解释:instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。其意思就是判断对象是否是某一数据类型(如Array)的实例,请重点关注一下是判断一个对象是否是数据类型的实例。在这里字面量值,2, true ,‘str‘不是实例,所以判断值为false。眼见为实,看下面的例子:

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

字面值被实例化了,他们的判断值变为了 true。

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

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

浏览器认为null,undefined不是构造器。但是在 typeof 中你可能已经发现了,typeof null的结果是object,typeof undefined的结果是undefined ,这是怎么回事呢?

尤其是null,其实这是js发展过程中设计者的重大失误,早期准备更改null的类型为null,由于当时已经有大量网站使用了null,如果更改,将导致很多网站的逻辑出现漏洞问题,就没有更改过来,于是一直遗留到现在。作为学习者,我们只需要记住就好。

3. constructor

  1.  
    console.log((2).constructor === Number);
  2.  
    console.log((true).constructor === Boolean);
  3.  
    console.log((‘str‘).constructor === String);
  4.  
    console.log(([]).constructor === Array);
  5.  
    console.log((function() {}).constructor === Function);
  6.  
    console.log(({}).constructor === Object);

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

用costructor来判断类型看起来是完美的,然而,如果我创建一个对象,更改它的原型,这种方式也变得不可靠了。

  1.  
    function Fn(){};
  2.  
     
  3.  
    Fn.prototype=new Array();
  4.  
     
  5.  
    var f=new Fn();
  6.  
     
  7.  
    console.log(f.constructor===Fn); // false
  8.  
    console.log(f.constructor===Array); // true

如此轻易的更改了contructor,到这里,你可能会想有没有一种最精准的方式去判断数据类型呢?接下来是终极大绝招,奥特曼也是总是到最紧急的时候才出现,这样才能体现价值所在。

4. Object.prototype.toString.call()

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

使用 Object 对象的原型方法 toString ,使用 call 进行狸猫换太子,借用Object的 toString  方法

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

结果精准的显示我们需要的数据类型。

就算我们改变对象的原型,他依然会显示正确的数据类型。

JS中数据类型的判断( typeof,instanceof,constructor,Object.prototype.toString.call() )

上一篇:css进阶 01-CSS中的非布局样式


下一篇:网站建设最主要的部分:让产品展示更有吸引力