3

I was just reading this answer regarding hashing in Javascript, and, while it was definitely faster than the accepted answer, it requires the reduce function on the Array prototype.

Checking the existence of the reduce function is easy enough; but while most checks I do (and have seen) check against the prototype, it just made me wonder: what are the implications of checking against an instance itself? Why does the prototype check seem to be preferred?

// i.e.

if (!!Array.prototype.reduce) { }
// vs
if (!![].reduce)

The instance will definitely need an instance, so that's one thing, but is that it?

Community
  • 1
  • 1
Richard Neil Ilagan
  • 14,627
  • 5
  • 48
  • 66
  • 2
    `Array` can *technically* be overwritten, but the constructor `[]` cannot – Ian Jun 25 '13 at 01:20
  • 2
    @Ian—if Array is overwritten, you've got bigger issues to deal with… ;-) – RobG Jun 25 '13 at 01:30
  • either way, you can omit the "!!" since methods "if" to true or undefined, which is false... If you're checking for an array method, you probably have an array already, so you don't need the empty one to hit "if(myArr.reduce)", and sniffing your exact variable is more accurate to boot. – dandavis Jun 25 '13 at 02:07
  • The main argument will be that `[]` is much shorter to type… – Bergi Jun 25 '13 at 02:18
  • @dandavis ~ your second point is fair, but not applicable if, for example, I'm writing an extension of a plugin most probably, as I'd most probably be operating on a "much more general" sense. As for the `!!`, I write it whenever I explicitly want a boolean, just to be clear (to others, and to myself). True enough on the `if` though. – Richard Neil Ilagan Jun 25 '13 at 03:31

2 Answers2

3

Just ran a benchmark: http://jsperf.com/prototype-vs-instance-property-check

Array.prototype.reduce is 3x faster due to the instantiation of an empty array, but realistically, there is absolutely no difference since these checks are almost always one-time checks, and not in code that runs all the time.

I personally have reduced this to [].method for years. I do the same for things like Array.prototype.slice.call( .. ) vs [].slice.call( ... ), and those are called far more often than once.

But note that this is only valid on Array, so you're really not saving a lot.

2

The second version involves needlessly instantiating an empty array. Why do so, when you can just ask the prototype itself and not instantiate anything?

user229044
  • 232,980
  • 40
  • 330
  • 338
  • I did mention that, but was just wondering if that was all there was to it. Not to say that the overhead is negligible though; I recognize this *and* perform the `prototype` check even for just this reason. – Richard Neil Ilagan Jun 25 '13 at 01:26
  • @RichardNeilIlagan I think that besides inintiating an empty array to invoke the function ([].reduce) the JS runtime has to look up the object instance prototype chain to find it. Where as Array.prototype.reduce tells the runtime exactly where to find it. – HMR Jun 25 '13 at 01:51
  • 3
    @HMR—actually, the lookup on an instance's `[[Prototype]]` is shorter and therefore *should* be faster as an empty array only has one property (*length*) to check. So the lookup will go almost directly to the prototype. With the pure property method, the identifier *Array* must be resolved on the scope chain before starting to look for *prototype* amongst Array's properties (there are two). But using an instance may not be faster as resolving identifiers in the global scope seems very fast (it's almost as if browsers check global before the local variable object). – RobG Jun 25 '13 at 03:18