javascript – From Array to pseudo-array

Question:

Many people ask how to turn NodeList, HTMLColletion and other pseudo-array into Array. So I need the opposite. That is, I need to turn an Array, for example, into a NodeList.

How to do it?

There are two "buts":

  1. I don't know what exactly I have: NodeList, HTMLColletion or some other pseudo-array; but I have a pseudo-array with that proto to turn the array into.
  2. Do not offer options with a change through the __proto__ parameter, since I need an option that will work at least in IE10

Answer:

Unfortunately, there is no way to artificially create a pseudo-array (array-like object) like NodeList and HTMLCollection, even with the help of the __proto__ property.

When you change the __proto__ of an array, it will simply change the "parent" from Array to whatever you specify when you change it. This will change the standard properties from Array.prototype to [{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>

As you can see from the example, the array has not ceased to be an array, but purely visually and by the type of object, it looks like a NodeList.

Technically, a pseudo-array can be any object that has a length property internally, which must be a positive integer. At least Array.from() pays attention mainly to this property.

 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'}) );
Scroll to Top