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

问题描述 投票:16回答:3

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

console.dir(document);

在Chrome中,我看到了以下内容:

enter image description here

这似乎意味着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);

enter image description here

对于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片段?或者,某些预定义对象(如DOM对象)是否只是常规日志记录行为的例外?

我知道如何以编程方式调用getter,我只是对看似不一致感到好奇。

javascript console getter prototypal-inheritance
3个回答
1
投票

是否可以创建一个具有与这些相同的日志记录行为的对象,其中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);

enter image description here

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


0
投票

有几点需要注意。

  1. 首先,控制台。*语句(除了.error)是异步的,您通过引用传递文档对象,实际上可能会在将其传递给console.FN和实际输出到日志窗口之间进行更改。
  2. 其次,在审讯方面,浏览器可以通过JS API直接访问。
  3. 第三,文档本身可能有一个继承链,其中包含域,而不是文档实例本身的一部分。
  4. 第四,并非所有属性都可以按设计迭代,但可能仍会显示在日志中(参见上面的#2)

-3
投票

如果对象具有指定的属性作为其自己的属性(而不是继承它),则document.hasOwnProperty()语句仅返回true。在此原因中,domain属性继承自HTMLDocument对象。 HTMLDocument是文档的原型。所以它返回false。

© www.soinside.com 2019 - 2024. All rights reserved.