Hello, I am interested in how the NodeList object is arranged and others like it.

enter image description here

  1. Why is it a NodeList displayed as an array of childNodes: NodeList[9] , and not so childNodes: NodeList and how was it done?
  2. elem.childNodes.length will work the getter on this property and possibly recalculate the contents, but why is it duplicated in the object and the prototype itself?
  3. And the most understandable to me, given the features above, why does the prototype name the same as the object, it inherits itself? What is it done for and how?

How to structurally create the same object? If possible.

  • In js, all objects, even a function, even an array. And then there are prototypes. Read about the prototypes, understand. - AlexOrtizzz
  • About the fact that I know all the objects, in the first question I conditionally compared it with an array. I also read about the prototypes, but among the objects “Animals” and “People” I did not find the answer to questions 2 and 3. - Jarry Roxwell
  • @JarryRoxwell, the previous question should be deleted, since I wrote a new one - Grundy
  • one
  • one
    there further there is a link to the specification for such collections . - Grundy

2 answers 2

NodeList - as mentioned earlier, this is an interface whose implementation is hidden in the depths of the browser. Therefore, what exactly the length property does and how it works specifically for this collection: recalculates each time it is accessed, or caches a value somewhere, you can find out only by immersing yourself in the source code of a specific browser.


As for the display of viewed objects in the console.

How exactly the console shows is for the most part unregulated. Therefore, in different browsers the output will look different.

If we consider specifically Chrome.


The name displayed opposite to proto can be determined using the property named Symbol.toStringTag

In addition, this property affects the operation of Object.prototype.toString

enter image description here


Now the most interesting thing: for output as an array, the console should think what output is an array.

The easiest way: inherit from the Array class

 class MyArr extends Array{ } 

enter image description here

But you can do with ordinary objects.

It is not clear what the developers were guided by, but if the object has a splice property, with a value as a function, as well as a length property, the Chrome console starts displaying this object as an array:

 var base = { get length(){return 0;} splice(){} } 

It will look like this in the console:

enter image description here

and in expanded form:

enter image description here

Now everything is ready to make the object very similar in the output to NodeList

 function NL() { this.splice = function() {}; } NL.prototype = { length: 0, // значение свойства по умолчанию push(el) { this[this.length] = el; this.length++; }, [Symbol.toStringTag]: "NL" }; var nl = new NL(); nl.push(10); nl.push(20); console.debug({ a: nl }); console.log(nl + ''); console.log(Object.prototype.toString.call(nl)); 

When you run the snippet in the Chrome console, you can see the following:

enter image description here

Which is very similar to the picture in question.

    1. This is a massive object. That is, an object whose keys are ordinal numbers is the length property. These objects are almost real-life arrays, so there are common features. By the way, the appearance of the tooltip depends on the browser. Someone will kindly tell the length, someone in brackets will deduce the nodes themselves (FF), and someone will deduce Object , who will be right, albeit rudely :)
    2. Getter is necessary due to the fact that it is, in fact, a "live" collection. That is, changes in the DOM, relative to the node, and recalculation occurs.
      The truth is rather a guess, I will be glad if the knower adds harsh rules.
    3. The name, as already mentioned, can be anything, depends on the browser. But it is logical that the object can be called in honor of the designer.

    At the expense of creating a similar object, I did not understand. Create a constructor, an object from it and voila.
    True, the name for the user object will only substitute chrome, the fox will contemptuously name the object as Object { ... } .

    PS Of course, you should not ignore the truth in the penultimate instance. Last resort here .
    Thanks @Grundy for the links, without it you would have to google :)

    • I didn’t understand how to create a similar object : chrome will simply mytype , not mytype[length] . :-) without certain conditions :) - Grundy
    • @Grundy, i.e. how to make the console output with the name and length? No, custom output only for types that are known to the console. Perhaps in the bright future, it will probably be automatically inferred by the length property. But this is the future. Likely. - user207618
    • not at all. but I found an option for chrome only :) - Grundy
    • @Grundy, share "how", monsieur! - user207618
    • Yes, I am going to write the answer here: -0 - Grundy