JS深入基础系列之数据类型判断

205 阅读3分钟

判断数据类型typeof、instanceof、Object.prototype.toString.call()、constructor


  • 先来看看instanceof

instanceof 期望左边是需要判断的 对象 ,注意是对象,所以instanceof是只能对于对象Object使用的,右边是标识对象的类(一个构造函数)

当instanceof判断左侧的对象Object是否是右侧类的一个实例的时候,也包含了对其父类的检测。如果instanceof的左侧不是一个对象,那么将返回false,如果右侧不是一个函数,那么将返回一个类型错误

instanceof的原理如下:

例子 o instanceof f

首先获取构造函数f的原型 f.prototype ,然后再原型链上查找,如果找的到,那么o就是f或者f父类的一个实例,返回true,若是不是的话,返回false。

另外的。由于右侧是构造函数,所以Object,Array,Data,Error,Function这些对象类型都是能放在右边的。instanceof的缺点在于不能获取类名,并且在客户端js中,因为每个窗口都有自己的执行上下文,包含了独有的一套全局变量和构造函数,这样会使得一个窗口的数组不是另一个窗口Array构造函数的实例。instanceof会返回false。

  • 然后是constructor

constructor是对象原型的一个属性,用来指向对象原型的构造函数。他会返回检测对象的类名。

注意:constructor的调用者不一定要是对象,因为若是在一个实例中找不到constructor属性,他会沿着原型链向上查找。

所以

var a = 1
a.constructor // [Function: Number]
a instanceof Number // false ,因为左边不是一个对象,是一个数值

所以constructor也是检测一个值是属于哪个类的一个方法。只不过他能返回类名,缺点也和instanceof一样,他在客户端js的多窗口情况下一样有问题。

  • typeof

typeof本质上是个一元运算符,他的操作数可以是任意类型。返回值是表示操作数类型的一个字符串

undefined      "undefined"
null           "object"
ture or false  "boolean"
任意数字和NaN   "number"
任意字符串      "string"
任意函数        "function"
出函数外的其他对象 "object" 

值得一提的是,在ES6暂时性死区概念出现之前,typeof运算符几乎可以算一个百分百安全的操作。

  • Object.prototype.toString.call()

对象的类信息是一个字符串(class attribute)用以表示对象的类信息。现在只有一种简介的方法可以查询它,就是使用默认的toString()方法(继承自object。prototype)返回以下格式的字符串

[Object class]

但是由于很多对象中的toString()方法都改写了,为了使用正确的toString,我们使用Funcrtion.prototype中的call方法来确保这一点

Object.prototype.toString.call(a).slice(8,-1)

以上截取了返回字符串的第八到最后一位,也就是class值,但是类信息不能区别自定义类,他只会返回Object

null // => Null
Number // => Number
undefined // => Undefined
String // => String
Boolean // => Boolean
Object // => Object
Array // => Array
Date // => Date
Error // => Error
自定义对象 // Object