2

I just need some explanation without any code samples. I know what is object, constructor and prototype. I just can't figure out how the relation between let say HTMLElement and HTMLDivElement looks like, or HTMLMediaElement and HTMLVideoElement. I know that there is something like prototypes chain, that the object has the access to the prototype of its constructor. But HTMLDivElement constructor is Function(), not HTMLElement(), on the other hand, in the HTMLVideoElement I have the access to all methods and properties of HTMLMediaElement prototype. I would be very grateful if someone could clarify it for me. So to sum up, what is the relation and what creates the chain between lets say function HTMLDivElement() -> function HTMLElement() -> function Element() -> function Node() -> function Object().

Paweł
  • 4,238
  • 4
  • 21
  • 40
  • Just an assumption. Were `HTMLDivElement` a subclass of `HTMLElement`, then `HTMLDivElement.prototype.constructor === HTMLElement`. But, prototypes and constructors of both seem to rely on browser native code. – pttsky Feb 16 '17 at 20:26
  • `HTMLElement` and `HTMLDivElement` etc. are not JS objects, they are [interfaces](https://developer.mozilla.org/en-US/docs/Web/API). – Teemu Feb 16 '17 at 20:32
  • 1
    It's not a chain between functions. It's a chain between their `.prototype` objects – Bergi Feb 16 '17 at 20:54
  • Bergi, so can I create the chains between `.prototype`s of my own objects the same way, to share their properties and methods between objects of non-the-same constructor? – Paweł Feb 16 '17 at 20:56

1 Answers1

2

There is a difference between user-created objects and those supplied by the platform (e.g. the web browser) in Javascript. The former are known as "native objects" and the latter as "host objects".

Native objects are likely to have helpful values for constructor and prototype. Host objects will normally not, because you can't construct them in the same way.

The actual property lookup is done using an internal prototype property. This can be found by using Object.getPrototypeOf or the __proto__ property. You can see the prototype chain by examining these. Note that __proto__ is much more readable and likely to work in modern web browsers, but Object.getPrototypeOf is the method recommended by the specification.

For example, presuming vid is a reference to a video node:

vid.__proto__ // the HTMLVideoElement object
vid.__proto__.__proto__ // the HTMLMediaElement object
vid.__proto__.__proto__.__proto__ // the HTMLElement object

// or equivalents

Object.getPrototypeOf(vid) // the HTMLVideoElement
Object.getPrototypeOf(Object.getPrototypeOf(vid)) // the HTMLMediaElement object
Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(vid))) // the HTMLElement object

It goes all the way up to

vid.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__ // === Object.prototype

// or

Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(vid)))))))

The way to see the "real" prototype chain is using this method.

Community
  • 1
  • 1
lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • 2
    `__proto__` is deprecated, please use `Object.getPrototypeOf` only – Bergi Feb 16 '17 at 20:55
  • @Bergi You're right, that was lazy of me. It's a much easier method to grasp and it is in the spec, but you're right that Object.getPrototypeOf is better. – lonesomeday Feb 16 '17 at 21:03