Из Array в псевдомассив

212
22 августа 2017, 15:20

Многие спрашивают, как NodeList, HTMLColletion и другой псевдомассив превратить в Array. Так мне нужно наоборот. То есть мне нужно превратить Array, к примеру, в NodeList.

Как это сделать?

Есть два "но":

  1. Я не знаю что у меня именно: NodeList, HTMLColletion или какой-то другой псевдомассив; но у меня есть псевдомассив с тем прото, в который нужно превратить массив.
  2. Варианты с изменением через параметр __proto__ не предлагать, так как мне нужен вариант, который сработает, как минимум, в IE10
Answer 1

К сожалению, искусственно создать псевдомассив (массивоподобный объект), вроде NodeList и HTMLCollection, никак нельзя, даже с помощью свойства __proto__.

Когда вы измените __proto__ массива, то он просто изменит "родителя" с Array на другой, который вы укажите при смене. Тем самым изменить стандартные свойства с Array.prototype на [{Object}].prototype.

var elements = document.querySelectorAll('div'); 
var array = [document.querySelector('div')]; 
 
// Изменяем прото массива 
array.__proto__ = NodeList.prototype; 
 
// Проверяем содержимое обоих элементов 
console.log(elements); // [<div></div>, item, entries, forEach, keys, values] 
console.log(array); // [<div></div>, item, entries, forEach, keys, values] 
 
// Провряем тип элементов 
console.log({}.toString.call(elements)); // [object NodeList] 
console.log({}.toString.call(array)); // [object NodeList] 
 
// Но тут сюрприз 
console.log(Array.isArray(elements)); // false 
console.log(Array.isArray(array)); // true
<div></div>

Как видно из примера, массив не перестал быть массивом, но чисто визуально и по типу объекта он выглядит, как NodeList.

Технически, псевдомассивом может быть любой объект, у которого внутри есть свойство length, которое должно быть целым положительным числом. По крайней мере, Array.from() обращает внимание в основном на это свойство.

Object.canAccessAsArray = function(object) { 
  return Number.isInteger(Number(object.length)) && Number(object.length) >= 0; 
}; 
 
// Тут выдаст массив с тремя пустыми значениями 
console.log( Object.canAccessAsArray({length: 3}) + ' => ' + Array.from({length: 3}) ); 
// А тут есть значения 
console.log( Object.canAccessAsArray({'0': 'a', '1': 'b', '2': 'c', length: 3}) + ' => ' + Array.from({'0': 'a', '1': 'b', '2': 'c', length: 3}) ); 
// А тут будет пустой массив, из за отсутствия length 
console.log( Object.canAccessAsArray({'0': 'a', '1': 'b', '2': 'c'}) + ' => ' + Array.from({'0': 'a', '1': 'b', '2': 'c'}) );

READ ALSO
Баг функции удаления элемента

Баг функции удаления элемента

Есть функция, которая должна обновлять массив пользовательских данных удаляя из него элементПо onClik в функциональный элемент передаётся...

155
Отладка не работает в хроме [требует правки]

Отладка не работает в хроме [требует правки]

Запускаю любой код, но консоль ничего не отображаетТолько модальные окна работают

179
как загрузить картинку из базы данных на админ-сайт

как загрузить картинку из базы данных на админ-сайт

Друзья есть база данных из которой мне надо выводить на сайте картинкуТо есть при клике на кнопку должна появляться картинка из базы данных

224
PHP. Google Charts. Error: Unknown header type: 3

PHP. Google Charts. Error: Unknown header type: 3

Подключил график на страницу, все работаетНо когда хочу добавить свои данные, то происходит ошибка Исходный код

300