Array.isArray
Array.isArray 判断值是否为规范意义上的数组对象,跨 iframe 比 instanceof 更可靠。
#type / concept
#status / evergreen
#resource / javascript
#resource / ecmascript
[!info] related notes
Array.isArray
一句话定义
Array.isArray(value) 判断值是否为规范意义上的数组对象,是数组判断的标准答案,ES5 引入。
用法
Array.isArray([]) // true
Array.isArray([1, 2, 3]) // true
Array.isArray({}) // false
Array.isArray('hello') // false
Array.isArray(undefined) // false
为什么数组需要单独 API
typeof [] === "object"— 不能区分数组和普通对象[] instanceof Array— 跨 iframe 时可能返回false
所以 ES5 专门提供了 Array.isArray()。
原理
它不是看原型链上是不是当前环境的 Array.prototype,而是判断该值是否具有数组的内部品牌(brand) / 内部槽特征。
可以理解为:“这东西是不是规范意义上的真正数组对象?”
因此跨 realm(iframe、Web Worker)更可靠。
跨 iframe 示例
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeArray = iframe.contentWindow.Array();
iframeArray instanceof Array // false(跨 realm 失效)
Array.isArray(iframeArray) // true(内部品牌判断有效)
等价手写实现
function myIsArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
Array.isArray 本质上做的事和 toString.call 判断数组是一样的,但语义更清晰。
与 instanceof Array 对比
| 特性 | Array.isArray | instanceof Array |
|---|---|---|
| 跨 iframe | 稳 | 可能失败 |
| 原始值 | false | false |
| 可被干预 | 否 | Symbol.hasInstance |
| 语义 | 内部品牌 | 原型链关系 |
缺点
只解决”数组”这一个问题,不是通用判断方案。