Hey.

I have a lot of questions about the Browser Object Model. Incomprehensible more than clear. I want to understand the structure of BOM.

Question 1: If you take a document, in the <body></body> element there is only ONE paragraph element (for simplicity) <p id="1"> </p> in my document with the id attribute = "1", then By analyzing the browser of my document, the browser IN MEMORY builds a BOM tree, where the DOM is included. My item becomes an object p . The p object deals with a SPECIFIC place in the BOM - window.document.lastChild(попал на объект html).lastChile(попал на объект body).firstChild(попал на объект p) . Question: WHERE PROTOTYPE CHAINS OF PARAGRAPH OF PARAGRAPHE - HTMLParagraphElement, HTMLElement, Element, Node ... are you a parent or a neighbor? " ( document.getElementById("1").__proto__.parentNode; ), then throws an Uncaught TypeError: Illegal invocation .

Question 2: There was an idea that maybe these prototype objects lie in the root of the window object (for the reason that all the variables created by the programmer, objects, prototype objects, and functions LIE IN THE ROOT of the window object) climbed and looked. I came across some strange constructor functions that have the same name as the prototype + they have the __proto__ property and the constructor SIMULTANEOUSLY. How can a constructor function have a prototype? I thought that the prototype can only be a normal object. enter image description here


enter image description here

Question 3: It turned out that the window object has a prototype WITH THE SAME NAME and even further prototypes go. And where are they? . I thought the window object is the topmost one. In general, some kind of confusion - "something in something inside something." Please help me get this mess.

    2 answers 2

    In order - it seems you are confusing soft with warm:

    WHERE ALL OBJECTS OF PROTOTYPE CHAIN ​​ARE LOCATED

    DOM system constructors do not have to lie somewhere. Firefox saw these prototypes in the source code - in the form of script files (not JS was there), perhaps.

    document.getElementById ("1"). proto ;), and ask, "Who is your parent or neighbor?"

    A prototype cannot have a parent in a DOM tree, because it is a prototype: a constructor of new elements, naturally, it is not tied to a DOM tree. Maybe the "parent class" of course - but this is different.

    How a constructor function can have a prototype

    Easy, read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf . A function is also an object, but which can be called. Moreover, with setPrototypeOf very funny jokes can be done

     var mutate = function(mutated, mutateBy) { if (arguments.length < 2) { throw new TypeError('Object.appendChain - Not enough arguments'); } if (typeof mutateBy === 'number' || typeof mutateBy === 'boolean') { throw new TypeError('second argument to Object.appendChain must be an object or a string'); } var rootProto, oLast; var oNewProto = mutateBy, result = rootProto = oLast = mutated instanceof Object ? mutated : new mutated.constructor(mutated); for (var o1st = Object.getPrototypeOf(rootProto); o1st !== Object.prototype && o1st !== Function.prototype; o1st = Object.getPrototypeOf(rootProto)) { rootProto = o1st; } if (mutateBy.constructor === String) { oNewProto = Function.prototype; result = Function.apply(null, Array.prototype.slice.call(arguments, 1)); Object.setPrototypeOf(result, oLast); } Object.setPrototypeOf(rootProto, oNewProto); return result; }; var list = [8, 3]; list = mutate(list, 'alert("Hello guys!!"+arguments.length+" "); return "ok";'); console.log(list[1]); /*logs 3*/ console.log(list(1, 2, 3)); /*alert, logs 'ok'*/ console.log(typeof list);/*logs 'function'*/ console.log(list instanceof Array);/*logs true*/ 

    Therefore, JS is the most flexible language)

    I thought the window object is the topmost one.

    Above the window there is a browser object - it is the topmost one, but it is not accessible from the web page.

    • document.getElementById ("1") .__ proto__; - I get on object HTMLParagraphElement. This is the first of the prototype object chain of the p object (which the browser created when it analyzed the <p id = "1"> </ p> element). The prototype chain is: p -> HTMLParagraphElement -> HTMLElement -> Element -> Node -> ... That is, properties and methods inside the Node object are available to the prototype object. Not only are they available, they are also defined (Uncaught TypeError: Illegal invocation). I meant neighbors or parents not by DOM, but by BOM - Dimon
    • once the HTMLParagraphElement.parentNode property; defined OUTSIDE the DOM (it is equal to the incomprehensible Uncaught TypeError: Illegal invocation), then, in theory, it should give the parent object in the BOM tree - Dimon
    • The fact that the properties of the parent prototypes are available to the prototype object is not surprising. And you do not give this property - because just getting from the page is limited. Because of security, for example, such restrictions are frequent. There is also such a thing - like native objects, native functions - nothing can be done with them, they are strictly not written in JS. Unless you can extend prototypes with your own properties - which I would not strictly recommend, remembering the sad mootools. - Goncharov Alexander
    • 2
      You want in-depth JS in the browser - try it in the firefox plugin. There are fewer restrictions. In the JS plug-in god, he can even easily connect dll-ki - written, of course, not at all on JS. And from there f-ii, for example, connect and use WinAPI - Goncharov Alexander
    1. parentNode is a "property type" and not a regular property. To the programmer, it seems to be a common property, but in reality it is a pair of getter plus setter, which are functions and mimic the usual property. The “property type” parentNode can be called only from the inside , for example, of the p -object ( document.getElementById("red"). parentNode; ) "and similar - from the inside of the objects that came out of the document elements during the analysis, as getters and setters have" types of properties ”have this and these getters and setters are programmed only to call from inside paragraph p and other objects that are obtained from the elements. That is, in the whole chain of prototypes, the getters and setters are mainly calculating properties for objects (for an object-paragraph p ( document.getElementById("red"). parentNode; ) and similar - from inside the objects that came from ) is conducted on the fly in dynamics . that is, they are calculated only when referring to them, and not always there "sit", as usual properties. And when I wrote document.getElementById("red").__proto__.parentNode; the context was not the one in which the "type property" parentNode is programmed to work (there is a bunch of this ). That gave out garbage Illegal invocation .
    2. I wanted to find out where in the BOM tree the following objects lie: a) Constructor functions for prototype objects function HTML Name Element (), function HTMLElement (), function Element (), function HTMLDocument (), function Document (), function CharacterData () , function Text (), function Comment (), function Attr (), function Node () + b) Prototypes of the same name HTML Name Element, HTMLElement, Element, HTMLDocument, Document, CharacterData, Text, Comment, Attr, Node, which are created by the corresponding with the same name constructor functions + c) constructor functions of objects created by the programmer (Array, Number, Function, Object ..., prototype objects of objects created by the programmer (Array.prototype, Number.prototype, Functio n.prototype, Object.prototype ...

    And mistakenly used for this "type of property" (and on the actual function getters and setters), which are disguised as ordinary properties (for example, name: 1) parentNode, firstChild, firstElementChild and other prototype Node, Element, HTMLElement objects ... I thought, once the property is defined, then it should work even in the prototype object itself (in its context, that is, from within it). But then I did not know about the getters and setters.

    They don’t know exactly where they are attached to the window object, since there are no special properties and methods for this.