为什么 Array.isArray 算法是 ES5 执行类型检查?

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

在 SO 和 google 中找到的关于检查对象是否为数组的每个问题最有可能以这个解决方案结束

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

所有其他选择都有误报或不完全支持。

来源:

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

How to detect if a variable is an array

当我阅读 15.4.3.2 部分中的 ES5 规范时,发现所描述的函数 Array.isArray 算法在 IE9+、Chrome 5+、Firefox 4+ 中执行相同的检查, Opera 10.5+ 和 Safari 5+ 但是这个算法有两个额外的步骤。

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;
}

现在我的问题是他们为什么要先检查类型?是否有一种特殊情况,对于仍然具有 [[Array]] 内部 class 的对象,这将 return 为 false?

让我们看看算法:

  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.

算法包含此检查,因为不是对象的值没有 internal properties。但是由于算法访问值的内部 属性 [[Class]],它必须断言该值是一个对象。

这个检查对于 polyfill 来说确实是不必要的,因为它们不访问值的任何属性。但是,它确实使 polyfill 更接近规范。