devconcept
devconcept

Reputation: 3685

Why the Array.isArray algorithm is ES5 performs a type check?

Every question found in SO and google about checking if an object is an Array most likely end up with this solution

function isArray(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]'
}

All the other alternatives have false positives or are not completely supported.

Sources:

http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/

How to detect if a variable is an array

When I read the ES5 spec in section 15.4.3.2 found the described algorithm for the function Array.isArray that performs the same check in IE9+, Chrome 5+, Firefox 4+, Opera 10.5+ and Safari 5+ but this algorithm have two extra steps.

function isArray(obj) {
    if (typeof obj !== 'object') {
        return false;
    }
    // Here they check only against the [[Class]] part 
    // and of course they don't have to use the ugly Object.prototype.toString.call
    // but this is pretty much the same comparison
    if (Object.prototype.toString.call(obj) === '[object Array]') {
        return true;
    }
    return false;
}

Now my question is why do they check for type first? Is there an special case where this will return false for an object that still has the [[Array]] internal class?

Upvotes: 3

Views: 1087

Answers (1)

Felix Kling
Felix Kling

Reputation: 816580

Lets look at the algorithm:

  1. If Type(arg) is not Object, return false.
  2. If the value of the [[Class]] internal property of arg is "Array", then return true.
  3. Return false.

The algorithm contains this check because values that are not objects don't have internal properties. But since the algorithm accesses the value's internal property [[Class]], it has to assert that the value is an object.

This check is indeed unnecessary for polyfills, since they don't access any properties on the value. However, it does bring the polyfill closer to the spec.

Upvotes: 3

Related Questions