Почему объект 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()