Разница между использованием Array.isArray и экземпляром массива

Существует два способа выяснить, является ли массив массивом или объектом. Использование typeof item === "object"; вернет true для объекта и массива, поскольку массивы относительно новы для javascript, а массивы - это прототипы объектов (возможно, это неправильно сказано, не стесняйтесь исправлять меня). Таким образом, два способа, которые я знаю, чтобы определить, является ли массив Array:

Решение 1:

Array.isArray(item);

Решение 2:

item instanceof Array;

Мои вопросы:

  • В чем разница между этими двумя решениями?
  • Какое из этих двух является предпочтительным решением?
  • У чего более быстрое время процесса?

Ответ 1

1. В чем разница между этими двумя решениями?

isArray - это метод ES5, который не поддерживается старыми браузерами, но он надежно определяет, является ли объект массивом.

instanceof проверяет только, если Array.prototype находится в цепочке объектов [[Prototype]]. Он не работает при проверке массивов между кадрами, поскольку конструктор Array, используемый для экземпляра, скорее всего, будет отличаться от используемого для теста.

2.Какой из этих двух является предпочтительным решением?

"Предпочтительный" предполагает некоторый критерий отбора. Как правило, предпочтительным способом является:

if (Object.prototype.toString.call(obj) == '[object Array]')

который подходит для браузеров ES3 и работает в разных кадрах. Если рассмотрены только браузеры ES5, isArray, скорее всего, ОК.

3.Чтобы ускорить процесс?

Во многом не имеет значения, так как время обработки для обоих незначительно. Гораздо важнее выбрать надежную. Метод Array.isArray может быть добавлен в браузеры, у которых нет встроенного приложения, используя:

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

Ответ 2

  1. Разница между Array.isArray(item) и item instanceof Array

    Как упоминал в комментарии Феликс Клинг, instanceof Array не работает через iframes. Чтобы дать вам конкретный пример, попробуйте следующий код:

    var iframeEl = document.createElement('iframe');
    document.body.appendChild(iframeEl);
    iframeArray = window.frames[window.frames.length - 1].Array;
    
    var array1 = new Array(1,1,1,1);
    var array2 = new iframeArray(1,1,1,1);
    
    console.log(array1 instanceof Array);  // true    
    console.log(Array.isArray(array1));  // true
    
    console.log(array2 instanceof Array);  // false    
    console.log(Array.isArray(array2));  // true    
    

    Как вы видите в примере выше, массив, созданный с помощью конструктора Array в iframe (т.е. array2), не распознается как массив, когда вы используете instanceof Array. Тем не менее, он правильно идентифицируется как массив при использовании Array.isArray().

    Если вам интересно узнать, почему instanceof Array не работает с разными глобальными переменными (например, iframe или window), вы можете прочитать об этом здесь.

  2. Какое из этих двух является предпочтительным решением?

    В большинстве случаев instanceof Array должно быть достаточно. Однако, поскольку instanceof Array не работает корректно в iframes/window, Array.isArray() будет более надежным решением.

    Обязательно проверьте совместимость браузера. Если вам нужно поддерживать IE 8 или меньше, Array.isArray() не будет работать (см. Array.isArray() Mozilla).

  3. У чего более быстрое время процесса?

    Согласно этому jsperf, instanceof Array быстрее, чем Array.isArray(). Это имеет смысл, потому что Array.isArray() выполняет более надежную проверку и, следовательно, делает небольшой удар производительности.