首页 > 解决方案 > 当我查看 DOM 对象的 getter 属性时,控制台中发生了什么?

问题描述

在控制台中运行以下代码时:

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 组成。但是,我的印象是 getter 在控制台中显示为(...),就像在这张图片中一样,您必须单击它(...)来调用 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.dir的对象,其中对象也将立即调用原型链中的任何 getter,而不是显示(...)?我将如何修改我的theClass片段?或者,某些预定义的对象(如 DOM 对象)是否只是对正常的日志记录行为有一个例外?

我知道如何以编程方式调用吸气剂,我只是对看似不一致的情况感到好奇。

标签: javascriptconsolegetterprototypal-inheritance

解决方案


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

从理论上讲,是的,尽管它不会准确评估吸气剂(我不确定您看到的值是否在您 console.dir 时被评估)。您需要评估该属性。但是,使用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);

在此处输入图像描述

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


推荐阅读