如何判定一个变量是数组

最后更新:

一个不幸的消息,最近我厂因为资金的问题凉凉了,所以我得开始重新找工作了,最近应该会分享一些和面试题有关并且我觉得有意思的内容,
😁 正巧今天面试的时候被问到的一个面试题我觉得就挺有意思的题目:

你如何判断一个变量是数组?

因为得知公司要解散的消息后比较仓促,也就没有好好刷面试题直接就出去面了(无缝衔接实属渣男了),所以被问道这还算是比较经典面试题的时候,下意识就回答了使用 typeof 来判断,但是想起来不对啊,数组他是对象类型嘛!

😱 卧槽,踩坑里了。

就马上补充了一句:“emmmm….好像用 typeof 不行,数组返回的是 Object ,应该可以通过原型链上的 constructor 来判断….噢,通过 instanceof 也可以!”

不出意料因为踩坑了,紧接着面试官就追问了一句 “还有其它的方式吗?”
考虑了5秒左右答 “没有了,暂时想不起来更多的方式。”,面试官回:“还有一种 isArray 可以判断”

以前一直没有考虑过这种问题,去判断一个对象是否为数组的场景。所以我觉得就还蛮有意思的,所以回来之后想看看还有哪几种方式可以判断是否为数组。

按照谷歌出来的答案,一共有4种判断方式,那就按照我回答的和我后续了解到的顺序来列举吧!

第一种,就是通过原型链上的 constructor 来判断:

var a = []
a.constructor === Array
// true

就很简单,其实不加上 === Array 直接使用 a.constructor 就会输出 ƒ Array() { [native code] } 就可以知道是否会是数组了,不过是为了判断嘛,所以还是加上了。

第二种,通过 instanceof 来判断:

var a = []
a instanceof Array
// true

这个也很容易,其实其原理就和我上面提到的通过原型链上的 constructor 来判断类似,instanceof 会去检测构造函数的 prototype 属性是否出现在实例对象的原型链上。

第三种,通过 isArray 来判断

var a = []
Array.isArray(a)
// true

😄 和 instanceof 一样简单,但 isArray 是优于 instanceof 的。其原因是不同的全局环境(页面、frame)下 Array 构造函数是不同的,使用 instanceof 来判断是否为数组得保证创建数组的 Array 构造函数是同一个才可以。 不过无伤大雅一般都不会出现这种问题,大家知道即可。

第四种,通过 Object.prototype.toString 来判断:

var a = [];
Object.prototype.toString.call(a) === '[object Array]'
// true

这种就是属于比较花里胡哨的了,用到了 Object.prototype.toString 方法,再使用 call 来指定 this 的指向。虽然他很强,可以判断几乎所有类型,但是我觉得不是很靠谱。
毕竟 instanceof 都可能因为不同全局环境而导致判断出错。让我觉得依赖于原型上的属性和方法都有可能会有问题。

不过现在已经有了 Array.isArray() 了,就不用再考虑再纠结这些问题了,实践中使用它就行了。我们大概知道有过多少种判断数组的方式即可。
以上。


参考文档

typeof - JavaScript | MDN
Object.prototype.constructor - JavaScript | MDN
instanceof - JavaScript | MDN
Array.isArray() - JavaScript | MDN
Object.prototype.toString() - JavaScript | MDN
Function.prototype.call() - JavaScript | MDN

javascript 判断变量是否是数组(Array) - SegmentFault 思否
JavaScript:Object.prototype.toString方法的原理 - 紫云飞 - 博客园
JS判断是否是数组的四种做法 - 听风是风 - 博客园
Determining with absolute accuracy whether or not a JavaScript object is an array