-3

I've been reading this thread to check if argument is Array or String

Check if object is array?

The solution mentioned is:

function isArray(obj){
    return !!obj && Array === obj.constructor;
}

But I've written the following function

function isArray(obj) {
     return obj.join;
}

I've done some sample test. I'm finding array.join() returns faster result than object.constructor(). Am I missing something?

I thought Object.constructor() is the parent class hence faster, but I'm able to return faster results using obj.split. Does it mean the answer in the other SO post was incorrect?

Jsfiddle:

https://jsfiddle.net/vdpseotp/6/

Please explain.

Community
  • 1
  • 1
TechnoCorner
  • 4,879
  • 10
  • 43
  • 81
  • 2
    Why not just use the built in [`Array.isArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) ? – adeneo Oct 01 '16 at 04:52
  • 1
    What you're missing is probably that `var obj = {join : 'come together'}` fails epically, as it also has a `join` method, but isn't an array *(assuming you meant `join`, not `split` as neither arrays nor objects can be split)* – adeneo Oct 01 '16 at 04:54
  • @adeneon Oops. It's array join. Basically the question is: If i give an argument, I need to identify if the given argument is array or string. – TechnoCorner Oct 01 '16 at 05:22
  • 1
    Please fix your title. You're not asking about the perfomance of `join()`. You're asking about the performance of using the presence of `join` on an object to guess its type. –  Oct 01 '16 at 05:31
  • Two proper ways of checking if an object is an array is `Array.isArray()` and the `instanceof` operator such as `a instanceof Array` For more info on these two you may check [this](http://stackoverflow.com/q/22289727/4543207) topic. – Redu Oct 01 '16 at 05:51

1 Answers1

4

The approach of using obj.join is sometimes called "duck-typing". Using join as you propose will fail miserably if you use it on an object which happens to contain a join property.

Just use the APIs which are designed for the task, such as Array.isArray, or a routine from a utility library. They have already thought through all of the issues. For example, Underscore uses Object.prototype.toString.call(obj) === '[object Array]'. There is also an extensive literature right here on SO on the topic, starting with the one you mention.

The more basic question is, why do you have things and don't know whether they are arrays or not? Perhaps some utility routines for traversing arbitrary objects might need to check for array-ness, or a server might send down something that might or might not be an array, but a well designed user-program should already know which objects are what. To put it a different way, if you were ever to move to a typed approach such as TypeScript, what type would you propose to assign to these maybe-an-array-maybe-not objects? Would you use any, which sort of defeats the whole purpose?

The second question is, why are you obsessing over a few microseconds? Do you have a game which is recalculating the position of hundreds of thousands of objects, sixty times per second? If not, it doesn't matter. If it does matter, see previous paragraph, and refactor your code so as not to have to check for something being an array all the time.

By the way, a meaningful benchmark should be run a million times. FWIW, console.time[End] often comes in handy for quick-and-dirty benchmarks. Anyway, according to your fiddle, the time difference is nothing more than a factor 1.5 or so at worst.

Minor note: Array === obj.constructor is not going to play well with subclasses of Array.

Community
  • 1
  • 1