在控制台中运行以下代码时:
console.dir(document);
在Chrome中,我看到了以下内容:
这似乎意味着domain
属性直接在document
对象上。但事实并非如此。
console.log(document.hasOwnProperty('domain'));
在Chrome 72中,上升原型链,它似乎在Document.prototype
上:
console.log(Document.prototype.hasOwnProperty('domain'));
console.log(Object.getOwnPropertyDescriptor(Document.prototype, 'domain'));
(在FF 56和其他一些浏览器中,它似乎是在HTMLDocument.prototype
而不是)
从片段中可以看出,该属性实际上由一个getter和一个setter组成。但是,我认为吸气剂在控制台中显示为(...)
,就像在this image中一样,你必须点击(...)
来调用吸气剂。
如果我创建一个类似的对象,其原型包含getter / setter属性,并且我记录了该对象,则在检查时不会调用getter:
// 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);
对于document
上的许多属性,可以看到相同的行为。例如,您可以在第一个屏幕截图中看到的所有其他属性在其中一个原型对象上看起来都是getter / setter,而且它们都不在document
本身上:
console.log(
['dir', 'doctype', 'documentElement', 'documentURI', 'embeds', 'fgColor', 'firstChild', 'firstElementChild']
.some(prop => document.hasOwnProperty(prop))
);
您还可以在window
属性以及元素上看到这一点。这也发生在FF中。
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">
是否有可能创建一个具有与这些相同的日志记录行为的对象,其中console.dir
ing对象也将立即调用原型链中的任何getter,而不是显示(...)
?我如何修改我的theClass
片段?或者,某些预定义对象(如DOM对象)是否只是常规日志记录行为的例外?
我知道如何以编程方式调用getter,我只是对看似不一致感到好奇。
是否可以创建一个具有与这些相同的日志记录行为的对象,其中console.diring对象也将立即调用原型链中的任何getter,而不是显示(...)?
理论上,是的,尽管它不会完全评估getter(我不确定你看到的值是否会在你控制它们时被评估)。您需要评估该属性。但是,使用hasOwnProperty
将返回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);
有几点需要注意。
如果对象具有指定的属性作为其自己的属性(而不是继承它),则document.hasOwnProperty()
语句仅返回true。在此原因中,domain属性继承自HTMLDocument对象。 HTMLDocument是文档的原型。所以它返回false。