简体   繁体   English

当我在DOM对象上查看getter属性时,控制台中发生了什么?

[英]What is happening in the console when I look at getter properties on DOM objects?

When running the following code in the console: 在控制台中运行以下代码时:

console.dir(document);

In Chrome, I see, among other things: 在Chrome中,我看到了以下内容:

在此输入图像描述

This seems to imply that the domain property is directly on the document object. 这似乎暗示domain属性直接在document对象上。 However, it isn't. 但事实并非如此。

 console.log(document.hasOwnProperty('domain')); 

In Chrome 72, going up the prototype chain, it appears to be on Document.prototype : 在Chrome 72中,上升原型链,它似乎在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) (在FF 56和其他一些浏览器中,它似乎在HTMLDocument.prototype

As you can see from the snippet, the property is actually composed of a getter and a setter. 从片段中可以看出,该属性实际上由一个getter和一个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. 但是,我的印象是,getters在控制台中显示为(...) ,就像在这张图片中一样 ,你必须点击(...)来调用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: 如果我创建一个类似的对象,其原型包含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); 

在此输入图像描述

The same sort of behavior can be seen for many properties on document . 对于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: 例如,您可以在第一个屏幕截图中看到的所有其他属性在其中一个原型对象上看起来都是getter / setter,而且它们都不在document本身上:

 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. 您还可以在window属性以及元素上看到此信息。 This happens in FF as well. 这也发生在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"> 

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 (...) ? 是否可以创建一个具有与这些对象相同的日志记录行为的对象,其中console.dir对象也将立即调用原型链中的任何getter,而不是显示(...) How would I modify my theClass snippet? 我该如何修改我的theClass片段? Or, do certain predefined objects (like DOM objects) just have an exception to the normal logging behavior? 或者,某些预定义对象(如DOM对象)是否只是常规日志记录行为的例外?

I know how to invoke the getters programmatically, I'm just curious about the seeming inconsistency. 我知道如何以编程方式调用getter,我只是对看似不一致感到好奇。

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 (...)? 是否可以创建一个具有与这些相同的日志记录行为的对象,其中console.diring对象也将立即调用原型链中的任何getter,而不是显示(...)?

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). 理论上,是的,尽管它不会完全评估getter(我不确定你看到的值是否会在你控制它们时被评估)。 You need to evaluate the property. 您需要评估该属性。 However, using hasOwnProperty will return true. 但是,使用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); 

在此输入图像描述

Working fiddle: https://jsfiddle.net/vL6smo51/1/ 工作小提琴: https//jsfiddle.net/vL6smo51/1/

There's a few things to be aware of. 有几点需要注意。

  1. First is that the console.* statements (other than .error) are async, you are passing the document object by reference that may in fact change between passing it to console.FN and the actual output to the log window. 首先,控制台。*语句(除了.error)是异步的,您通过引用传递文档对象,实际上可能会在将其传递给console.FN和实际输出到日志窗口之间进行更改。
  2. Second, is that the browser has access to more than you might via the JS API directly in terms of interrogation. 其次,在审讯方面,浏览器可以通过JS API直接访问。
  3. Third is that document itself may have an inheritance chain that includes things like domain which is not a part of the document instance itself. 第三,文档本身可能有一个继承链,其中包含域,而不是文档实例本身的一部分。
  4. Fourth is that not all properties are iterable by design, but may still show up in the log (see #2 above) 第四,并非所有属性都可以按设计迭代,但可能仍会显示在日志中(参见上面的#2)

document.hasOwnProperty() statement only returns true if the object has the specified property as its own property (as opposed to inheriting it). 如果对象具有指定的属性作为其自己的属性(而不是继承它), document.hasOwnProperty()语句仅返回true。 In this cause domain property is inherited from HTMLDocument object. 在此原因中,domain属性继承自HTMLDocument对象。 HTMLDocument is the prototype of document. HTMLDocument是文档的原型。 So it returns false. 所以它返回false。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM