The browser console allows you to inspect an object using a tree structure, for example like this:
console.log(document);
I can then freely browse the object, including its prototype, and the prototype of the prototype and so on. I want to replicate this behavior but ran into an issue while implementing the "prototype of prototype" feature.
My code works fine for getting the keys within the prototype, but throws an error when trying to log them. (I am using var
to make it easier to repeatedly test this in the console.)
Here is a simplified version demonstrating the issue:
var prototype = Object.getPrototypeOf(document);
var prototypeOfPrototype = Object.getPrototypeOf(prototype);
// This works, so the values are there
var keys = Object.getOwnPropertyNames(prototypeOfPrototype);
console.log(keys);
var values = keys.map((key) => {
// This throws an error although it shouldn't be executing anything here
console.log(prototypeOfPrototype[key]);
});
The errors I am getting are as follows:
Chrome:
"Illegal invocation"
Firefox:
"Uncaught TypeError: 'get implementation' called on an object that does not implement interface Document."
Which aren't really helpful, to me at least. If anyone knows why this happens or how I can implement this feature while avoiding the error it would be greatly appreciated.
This will happen when you are accessing a getter on an object where it is not supposed to be accessed on, in this case the prototype and not document
(the actual instance). I would therefore recommend to use Object.getOwnPropertyDescriptors
instead of Object.getOwnPropertyNames
:
var prototype = Object.getPrototypeOf(document);
var prototypeOfPrototype = Object.getPrototypeOf(prototype);
var properties = Object.getOwnPropertyDescriptors(prototypeOfPrototype);
for (const [key, descriptor] of Object.entries(properties)) {
const value = "value" in descriptor ? descriptor.value : descriptor.get.call(document);
console.log(key, typeof value);
}