Почему объект FileList не является массивом?

Документация: https://developer.mozilla.org/en-US/docs/Web/API/FileList

Почему FileList объект, а не массив? Единственное свойство, которое у него есть, - это .length, и единственным способом, который он имеет, является .item(), который является избыточным (fileList[0] === fileList.item(0)).

Ответ 1

Ну, может быть несколько причин. Например, если бы это был массив, вы могли бы изменить его. Вы не можете изменить экземпляр FileList. Во-вторых, но связанных, это может быть (вероятно, является) представление о структуре данных браузера, поэтому минимальный набор возможностей облегчает реализацию.

Обновление в 2018: Интересно, что в спецификации есть примечание к FileList:

Интерфейс FileList следует рассматривать как "подверженный риску", поскольку общая тенденция на веб-платформе заключается в замене таких интерфейсов на объект платформы Array в ECMAScript [ECMA-262]. В частности, это означает, что синтаксис вида filelist.item(0) находится под угрозой; на большинство других программных применений FileList вряд ли повлияет возможный переход к типу Array.

(Что я нахожу странным, я думал, что тенденция была к iterable, а не к Array - такому как обновление NodeList помечающее его как iterable для совместимости с синтаксисом расширения, for-of и forEach.)

Вы также можете преобразовать его в массив через Array.from(theFileList).

Ответ 2

С помощью es6 мы можем теперь

const files = [...filesList]

Полезно, например, если вы хотите map над этими

Ответ 3

Если вы хотите использовать методы массива в FileList, попробуйте apply

Итак, например:

Array.prototype.every.call(YourFileList, file => { ... })

если вы хотите использовать каждый

Ответ 4

Я думаю, что его собственный тип данных, потому что объектно-ориентированное программирование было чем-то большим, чем функциональное программирование, когда оно было определено. Но современный Javascript предлагает функциональность для переноса массива типа Datatypes в массивы.

Например, как Тим описал: const files = [...filesList]

Другим способом итерации FileList с ES6 является метод Array.from().

const fileListAsArray = Array.from(fileList)

IMO лучше читается, чем оператор спредов. Но, с другой стороны, более длинный код:)

Ответ 5

Вот пара полифилов, которые добавляют функцию toObject() в File и функцию toArray() в FileList:

File.prototype.toObject = function () {
  return Object({
    lastModified: parseInt(this.lastModified),
    lastModifiedDate: String(this.lastModifiedDate),
    name: String(this.name),
    size: parseInt(this.size),
    type: String(this.type)
  })
}

FileList.prototype.toArray = function () {
  return Array.from(this).map(function (file) {
    return file.toObject()
  })
}

var files = document.getElementById('file-upload').files
var fileObject = files[0].toObject()
var filesArray = files.toArray()