When running the following code in the console:
console.dir(document);
In Chrome, I see, among other things:
This seems to imply that the domain
property is directly on the document
object. However, it isn't.
console.log(document.hasOwnProperty('domain'));
In Chrome 72, going up the prototype chain, it appears to be on Document.prototype
:
console.log(Document.prototype.hasOwnProperty('domain'));
console.log(Object.getOwnPropertyDescriptor(Document.prototype, 'domain'));
(In FF 56 and perhaps some other browsers, it appears to be on HTMLDocument.prototype
instead)
As you can see from the snippet, the property is actually composed of a getter and a setter. But, I was under the impression that getters are shown in the console as (...)
, like in this image, which you had to click on the (...)
to invoke the getter.
If I create a similar object, one whose prototype contains a getter/setter property, and I log the object, the getter does not get invoked while examining it:
// look at results in Chrome's browser console, not snippet console
class theProto {
get foo() {
return 'fooVal';
}
set foo(arg) {
// do something
}
}
class theClass extends theProto {
}
const instance = new theClass();
console.dir(instance);
The same sort of behavior can be seen for many properties on document
. For example, all of the other properties you can see in the first screenshot also appear to be getters/setters on one of the prototype objects, and none of them are on document
itself:
console.log(
['dir', 'doctype', 'documentElement', 'documentURI', 'embeds', 'fgColor', 'firstChild', 'firstElementChild']
.some(prop => document.hasOwnProperty(prop))
);
You can also see this on window
properties, as well as elements. This happens in FF as well.
const input = document.createElement('input');
// console.dir(input);
// but the own property list is empty!
console.log(Object.getOwnPropertyNames(input));
<img src="https://i.stack.imgur.com/R5u3S.png">
Is it possible to create an object with the same logging behavior as these, where console.dir
ing an object will also invoke any getters in the prototype chain immediately, instead of displaying (...)
? How would I modify my theClass
snippet? Or, do certain predefined objects (like DOM objects) just have an exception to the normal logging behavior?
I know how to invoke the getters programmatically, I'm just curious about the seeming inconsistency.
Is it possible to create an object with the same logging behavior as these, where console.diring an object will also invoke any getters in the prototype chain immediately, instead of displaying (...)?
Thecnically, yes, despite it will not exactly evaluate the getters (I'm not sure whether the values you see are evaluated when you console.dir them). You need to evaluate the property. However, using hasOwnProperty
will return true.
// look at results in Chrome's browser console, not snippet console
class theProto {
get foo() {
return 'fooVal';
}
set foo(arg) {
// do something
}
}
class theClass extends theProto {
foo = (() => theProto.prototype.foo)(); // or, really, just (() => this.foo)();
}
const instance = new theClass();
console.dir(instance);
Working fiddle: https://jsfiddle.net/vL6smo51/1/
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