Checking Array-ness in Javascript
Recently during an interview I was asked to implement a function that flattens a multi-level nested array. I kind of stumbled on how to robustly check for the array-ness in javascript, because I was being ambitious and tried to make the function work with not only Arrays, but also Array-like objects.
You probably know that using typeof on an array object always gives you ‘object’, so it’s pretty useless. In ECMAScript 5 we have the convenient Array.isArray() method, but that doesn’t work in older browsers. We can probably also use instanceof Array, but this can be a problem when you are working in a multi-frame environment, as the Array in one window is considered different from the Array in another window. The most robust way is to use Object.prototype.toString() and invoke it on the target object with call(). The expected result would be exactly “[object Array]“. We’re using the toString() method inherited from the Object prototype because Array and some other classes implement their own version of toString() which do not always behave the same. This technique also turns out to be the most robust method of type-checking in javascript for almost any kind of objects as described in this post by Angus Croll, and is used by the latest version of jQuery.
On top of this, I found that jQuery is using the following method to check for Array-like objects:
isArray = elems instanceof jQuery || length !== undefined && typeof length === “number” && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
The first and last conditions are checking for a jQuery collection and a real Array respectively, and the things in between are essentially checking to see if the object has a length property which is a number, and that it actually contains a first element (at [0]) and a last element (at [length-1]). (or simply is empty with a length of 0). This is what I came up with after the interview (I settled for a real Array checking just to get by). I originally thought it was pretty crude, as the object can be really sparse and still pass this check. But after some thought, it seems to be ok, because being sparse doesn’t interfere with the ability to use Array prototype methods on the Array-like object, as long as the length property matches the largest index.
-
http://weibo.com/shenzhenyu <script>沈振宇1</script>
-
http://youyuxi.com 尤小右
-