Вы не можете быть абсолютно уверены, но если человек, предоставляющий вам объект, активно пытается ввести вас в заблуждение, вы можете сделать это:
if (arr.constructor === Array) {
// Yes, it is
}
Но , будьте осторожны: если вы получите arr
из другого царства (такого как дочернее или родительское окно), эта проверка будет ложной, поскольку arr.constructor
будет ссылаться в конструктор Array
в этой другой области, который не является ===
конструктором 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
. Если бы arr
был экземпляром подкласса, там был бы другой слой. И это работает кросс-царство. Он может также быть побежден кем-то, кто активно пытается ввести вас в заблуждение (используя Object.setPrototypeOf
), но ...