Как проверить, является ли массив простым встроенным массивом? - PullRequest
0 голосов
/ 04 ноября 2018

Учитывая, что теперь любой может расширять встроенные типы, как правильно проверить, является ли данный массив настоящим старым базовым массивом JavaScript, а не какой-то расширенной версией?

Что я пробовал:

arr instanceof Array // true for child classes, too
Array.isArray(arr)   // same

Есть ли другой способ?

1 Ответ

0 голосов
/ 04 ноября 2018

Вы не можете быть абсолютно уверены, но если человек, предоставляющий вам объект, активно пытается ввести вас в заблуждение, вы можете сделать это:

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), но ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...