Вы действительно конвертируете массивы в массивы?

JavaScript опрос
Вы действительно конвертируете массивы в массивы?

Во-первых, что такое массив?

Простое определение, если объект имеетlengthзначение свойства, это массив

Каковы распространенные типы массивов?

Это очень распространено в DOM, например, различные API-интерфейсы для извлечения элементов возвращают массивы, такие какdocument.getElementsByTagName,document.querySelectorAllи т.п. Помимо DOM API, общийfunctionсерединаargumentsтакже похожий на массив

Так как же преобразовать массив классов в массив? Это типичный сценарий для операций с массивами и типичный вопрос на собеседовании.

Ниже мы{ length: 3 }ссылаться на массив, как демонстрацию

выдержка изяпонский язык 【Q168】Как преобразовать массив классов в массив в js. Также здесь большеВопросы на фронтенд-интервью, добро пожаловать на обмен

ES6+

ES6Есть готовые API:Array.from, очень простой

// [undefined, undefined, undefined]
Array.from({ length: 3 })

КромеArray.fromЕсть более простые операторы...оператор распространения, но он работает только наiterableОбъекты, которые имеютSymbol(Symbol.iterator)значение атрибута

имеютSymbol(Symbol.iterator)значение свойства, что означает, что вы можете использоватьfor ofповторять

// 适用于 iterable 对象
[...document.querySelectorAll('div')]

Но, строго говоря, он не может преобразовать массив классов в массив, например{ length: 3 }. это вызовет исключение

// Uncaught TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
[...{length: 3}]

ES5

До этого давайте не будем использовать его первым.{ length: 3 }, используя следующие данные для представления массива

const arrayLike = {
  0: 3,
  1: 4,
  2: 5,
  length: 3
}

существуетES5можно одолжитьArray APIпройти черезcall/applyИзменятьthisилиargumentsдля завершения преобразования.

Наиболее распространенными преобразованиями являютсяArray.prototype.slice

Array.prototype.slice.call(arrayLike)

Конечно из-за кредитаArray APIлюбой API, который принимает массив в качестве входных данных и принимает массив в качестве выходных данных, может выполнять преобразование массива, например

  • Array(занять аргументы)
  • Array.prototype.concat(занять аргументы)
  • Array.prototype.slice(заимствуя это)
  • Array.prototype.map(заимствуя это)
  • Array.prototype.filter(заимствуя это)
Array.apply(null, arrayLike)
Array.prototype.concat.apply([], arrayLike)
Array.prototype.slice.call(arrayLike)
Array.prototype.map.call(arrayLike, x => x)
Array.prototype.filter.call(arrayLike, x => 1)

На данный момент все работает нормально, но забыл особый случай, разреженные массивы. Перед этим задайте вопрос, сколько выводит следующий код?

// 该代码输出多少
Array(100).map(x => 1)

Ссылаться накаков результат Array(100).map(x => 1)

разреженный массив

использоватьArray(n)Будет создан разреженный массив.Для экономии места разреженный массив содержит ненастоящие элементы, которые будут отображаться в консоли какemptyдисплей, как показано ниже

[,,,]а такжеArray(3)вернет разреженный массив

> [,,,]
[empty × 3]
> Array(3)
[empty × 3]

Когда массив классов{ length: 3 }, все обрабатывает массив какthisвсе методы будут возвращать разреженные массивы, в то время как массивы, подобные массивам, будутargumentsвсе методы будут возвращать плотные массивы

Суммировать

Из приведенного выше резюме наиболее надежными способами преобразования массивов классов в массивы являются следующие три.

Array.from(arrayLike)
Array.apply(null, arrayLike)
Array.prototype.concat.apply([], arrayLike)

Следующие методы должны учитывать преобразование разреженных массивов

Array.prototype.filter.call(divs, x => 1)
Array.prototype.map.call(arrayLike, x => x)
Array.prototype.filter.call(arrayLike, x => 1)

Следующие методы должны обратить внимание на то,iterable object

[...arrayLike]

Я Шаньюэ, вы можете добавить меня в WeChatshanyue94Общение со мной, замечания и обмены. Кроме того, вы можете обратить внимание на мой паблик аккаунт [полный путь роста стека]

如果你对全栈面试,前端工程化,graphql,devops,个人服务器运维以及微服务感兴趣的话,可以关注我