【发布时间】:2019-07-13 23:33:08
【问题描述】:
在控制台中运行以下代码时:
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 上)
从sn-p可以看出,属性实际上是由getter和setter组成的。但是,我的印象是 getter 在控制台中显示为 (...),就像在 this image 中一样,您必须单击 (...) 才能调用 getter。
如果我创建一个类似的对象,其原型包含一个 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.diring 对象也将立即调用原型链中的任何 getter,而不是显示(...)?我将如何修改我的theClass sn-p?或者,某些预定义的对象(如 DOM 对象)是否只是对正常的日志记录行为有一个例外?
我知道如何以编程方式调用 getter,我只是对表面上的不一致感到好奇。
【问题讨论】:
-
实际上,如果您查看
document的__proto__链,您会发现domaingetter 和setter 与(...)评估。我认为您在那里看到的值不是Document接口的domain属性,正如您在本规范中看到的那样:html.spec.whatwg.org/multipage/dom.html#document,而是 DOM 元素的属性,它得到以某种方式列举。简而言之,在我看来,这样的属性特别是由console.dir评估的属性,而不是Document接口的属性值。 -
我认为真正做到这一点的唯一合理方法是通过使用自调用匿名函数评估其值来覆盖
theClass中的属性。这将导致与您提到的document相同的结果,从而导致对象具有foo评估和foo其祖先中的 getter 和 setter。 jsfiddle.net/vL6smo51 。我看到的唯一合乎逻辑的条件是Document正在评估HTMLDocument的一些属性,因此是值。 -
这似乎是a chrome devtools bug。奇怪的是,你也可以在 FF 中重现它……
-
@Bergi 这个问题看起来有点相似,但它不是一回事 - 在那里,getter 显示在原型链的所有级别上,这是不同的从 getter 被自动调用。
标签: javascript console getter prototypal-inheritance