鉴于现在任何人都可以扩展内置类型,我如何正确检查给定的数组是否是真正普通的基本JavaScript数组而不是某些扩展版本?
我尝试过的事情:
arr instanceof Array // true for child classes, too
Array.isArray(arr) // same
还有其他方法吗?
答案 0 :(得分:3)
您不能绝对确定,但是除非向您提供物体的人正在积极地试图误导您,否则您可以这样做:
if (arr.constructor === Array) {
// Yes, it is
}
但是,请注意:如果您从另一个领域(例如子窗口或父窗口)获得arr
,则该检查将为假,因为{ {1}}将引用该其他领域中的arr.constructor
构造函数,而不是您领域中的Array
的{{1}}构造子。
如果您需要将其作为纯数组,并且===
可能来自另一个领域,则可能要复制它:
Array
想到的另一个选择是:
arr
之所以可行,是因为普通数组的原型是arr = Array.from(arr);
,原型是function isReallyAPlainArray(arr) {
const getProto = Object.getPrototypeOf;
try {
// A plain array's prototype is Array.prototype, whose prototype is
// Object. prototype, whose prototype is null
return Array.isArray(arr) && getProto(getProto(getProto(arr))) === null;
} catch (e) {
// Prototype chain was too short; not a plain array
return false;
}
}
class MyArray extends Array { }
console.log(isReallyAPlainArray([])); // true
console.log(isReallyAPlainArray(new MyArray)); // false
,原型是Array.prototype
。如果Object.prototype
是子类的实例,则其中会有另一层。这是跨领域的。它也可以被某人主动试图误导您(使用null
)打败,但...