1. obj instanceof Array

我们都知道instanceof是用来判断对象的类型的,并且所有的对象 instanceof Object结果都是true

  • 内部机制是通过判断对象的原型链中是否能找到同类型的prototype
  • 其原理是一层一层查找__proto__,如果和constructor.prototype的值相等则返回true,否则返回false

根据这一点可得,如果想判断一个对象是否是数组,需要判断这个对象的原型链上是否存在Array的原型:

console.log([] instanceof Array)  // true
console.log([] instanceof Object)  // true

很容易可以发现这个方法有个问题是无法判断对象是属于Object还是Array。

2. Array.isArray( obj )

obj是待检测的对象,如果结果返回Array则整体返回true,否则该表达式返回false。

  • ES5新增的方法
  • Array.isArray()优于instanceof的地方在于:Array.isArray()可以检测iframes

3. Object.prototype.toString.call( obj )

obj是待检测的对象,这种方法能检测出所有的基本数据类型!

QUESTION:为什么要用到call()呢?

每个继承Object的对象都有toString()方法,在toString没有被重写的情况下,执行Object.prototype.toString会返回[object type],其中type是对象的类型。

  • 如果是个基本数据类型调用toString()方法,比如字符串或者是一个数字,那么toString()会直接返回内容的字符串
  • 如果直接调用Object.prototype.toString()的话,默认是指向Object,因此我们这里要调用call()或者apply()来改变toString的指向

 

        var str = 'hello';
        console.log(str.toString())  // hello
        console.log(Object.prototype.toString(str))  // [object Object]
        console.log(Object.prototype.toString.call(str))  // [object String]