Note: I've searched for this error, but everything I've found was about calling functions. I'm not calling any function. I'm just trying to access a property.
I get the error when I execute this simple code:
var a = document.getElementById("something");
var b = Object.create(a);
console.log(b.baseURI) //Throws error with any property of a
<p id="something">Hi! I exist just for demo purposes. This error can occur with any element.</p>
I have no idea of why this happens. The code works fine if I try to get the property from the prototype of b
...
var a = document.getElementById("something");
var b = Object.create(a);
console.log( Object.getPrototypeOf(b.baseURI) ) //Works
... and also using a normal object.
var a = {foo: "Foo!"};
var b = Object.create(a);
console.log(b.foo) //Works
Why does this happen? It makes no sense to me. MDN says:
When trying to access a property of an object, the property will not only be sought on the object but on the prototype of the object, the prototype of the prototype, and so on until either a property with a matching name is found or the end of the prototype chain is reached.
The prototype chain of b
(in the first example) is:
HTMLParagraphElement --> HTMLParagraphElement (the actual element object) --> HTMLParagraphElement --> HTMLElement --> Element --> Node --> EventTarget --> Object --> null
(Proof)
EDIT: Note how the 1st object in the proto chain is a HTMLParagraphElement
. This is normal, so that's not the problem. (Image)
The problem (i think) is that the proprieties get kinda copied to the main b
object and not just to b
's prototype. This means that the browser founds a matching name right in the first object and tries to access it, but it throws an error. (Image; clicking the (...)
results in error).
However, I still don't understand why this happens nor why the error is thrown.
This behavior is caused by the implementation of the specification. These DOM nodes are so-called 'platform objects' and the way they implement getters is slightly different from 'normal' javascript.
In short: they can not be extended without extra work.
var a = document.getElementById("something");
var b = Object.create(a);
When the baseURI
of b
is accessed, its this
points to b
which is not a valid 'platform object'. This causes the Illegal invocation
error. Accessing it through the prototype
does work because then its this
points to the prototype
which is a valid 'platform object'.
This comment on an issue of Chrome explains it in more detail and also supplies a workaround if you really need it: https://bugs.chromium.org/p/chromium/issues/detail?id=495437#c7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With