面试官:你是如何判断js数据类型的?

288 阅读2分钟

ECMAScript规范定义了7种数据类型,分为 基本类型 和 引用类型 两大类。接下来就让我们一起来探索这两种类型是如何区分的。 基本类型String Number Boolean Undefined Null Symbol
引用类型Object

1.typeof

typeof的使用方式: 在右侧跟一个一元表达式,返回结果为这个表达式的数据类型(字符串)。

// 以下几种数据类型可以做出正确判断
typeof '' // string
typeof 100  // number
typeof Symble('100') // symbol
typeof true // boolean
typeof undefined // undefined
typeof new Function() // function

// 以下几种数据类型不能做出正确判断
typeof null // object
typeof ['100'] // object
typeof new Date() // object
typeof new RegExp() // object

从上面的例子中可以看出来,typeof更适合处理基本数据类型,除了null返回Object类型,其它均返回正确的结果。

2.instanceof

instanceof的使用方式:A instanceof B 如果A是B的实例,则返回true,否则返回false。注意instanceof检测的是原型。当A的__proto__指向B的prototype时,就判断A为B的实例。

[] instanceof Array // true
[] instanceof Object // true

{} instanceof Object // true

new Date() instanceof Date // true
new Date() instanceof Object // true

function Animal() {}
new Animal() instanceof Animal // true
new Animal() instanceof Object // true

我们拿[]举例来看,通过instanceof可以判断出[]既是Array的实例,又是Object的实例,从这里就可以看出来instanceof检测的是原型。它们之间的关系如下:
[].__proto__指向Array.prototype,而Array.prototype.__proto__又指向了Object.prototype,最终Object.prototype.__proto__指向null,到此这样一条原型链结束。
[].__proto__ -> Array.prototype.__proto__ -> Object.prototype.__proto__ -> null
所以,由此可见instanceof只是判断出两个对象是否属于实例关系,而不能判断一个对象实例具体属于哪种类型

3.toString

对于Object对象直接调用toString()方法,默认返回[Object, Object]。而对于其它对象,则需要通过call/apply来调用返回正确的类型信息。

Object.prototype.toString.call('') // [object String]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(1) // [object Number]
Object.prototype.toString.call(Symbol()) // [object Symbol]
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([]) // [object Array]