Play with JS - isArray()

2018-09-09

概览

判断JS中一个变量是不是数组有很多方式,我在写TS的时候最常用的是a instanceof Array,虽然之前看过很多文章说这个非常靠谱因为他是不断递归对应变量的原型树,如果发现Array的话就返回true这个方式在 nodeJS 中确实是比较靠谱的但是在网页里还是有办法使其返回错误的结果。

我打算总结一下都有什么办法可以尝试判断一个变量是不是数组,而这些方法都有什么方式可以使其返回错误的结果。

流水的脚本,铁打的C++

在不考虑浏览器环境的情况下,最靠谱的方式是.node文件中调用V8原生的Value->IsArray()函数,这个函数返回一个原生C++boolean,从根本上判定其在栈上是以什么形式存在的,node 和浏览器亲切的帮我们封装了这个函数也就是Array.isArray(<arr>)这个方式可以说是最稳妥的。node 环境下不必说这个方法的通用性了,基本上无论是稳定性还是速度都是最快的,但是在古老的浏览器上,比如说不支持es5的浏览器可能这个函数就没法用了。

盲人摸象

网上有一些比较愚蠢的方法,这些方法在大多数情况下都是适用的,但是这些方法都存在一些小缺点:

(array instanceOf Array);

这个 instanceof 语法和 array.constructor === Array 跑起来很相似,就是检测最后面的Array对象是不是同一个。这样搞的问题在于,其他的副作用库可能会弄坏Array对象,使它指向不同的类,或者在浏览器环境中,service worker 或者 iframe 的多进程共享变量都会倒是 Array 指向克隆的 Array 对象导致方法失效。

Object.prototype.toString.call(array) === '[object Array]';

这种方式说实话在大多数情况都是适用的,除非目标对象是一个近似Array,也就是一个可迭代的对象,可迭代的对象可以使用for-of循环遍历,也可以简单的嵌套使用stream,但是对于这类的对象,此方法返回 [Object Object]

Go Back

随便看看 :D