16

我目前正在为 JavaScript 构建一个 API,主要使用 Visual Studio 2010 和 JetBrains WebStorm(如果您正在寻找一个防弹的 JavaScript IDE,那就太棒了)。

在查看 Visual Studio 中的智能感知列表时(试图让自己熟悉 JavaScript API),我注意到两者都Document存在document

  1. Document和 和有什么不一样document
  2. 什么是document(如果有的话)的实例?
  3. 如何使用Document(因为它不是函数,因此不可构造)?
  4. 最重要的是,“猴子补丁”Document使其可构造有什么害处?

这些问题背后的基本原理是我想创建一些适合我的 API 的对象(例如;DocumentHTMLElement),但由于这些对象在某些方面似乎已经存在,我不确定我应该覆盖它们的原生对象执行。

4

2 回答 2

17

Document和 和有什么不一样document

document(或window.document)是对包含在窗口中的文档的引用。(规格

Document是文档的 DOM 接口,它暴露在全局对象上。(规格规格

如何使用Document(因为它不是函数,因此不可构造)?

它是一个宿主对象,不需要遵循 EcmaScript 规范——但这并不意味着它不是一个函数。它也可能因浏览器而异。然而它并不打算被调用(如果你尝试它,你会得到一个NOT_SUPPORTED_ERR),还有其他方法可以实例化/获取新文档。您仍然可以使用它的是

> document instanceof Document
true
> Document.prototype
DocumentPrototype {
    adoptNode: Function
    constructor: Document
    createAttribute: Function
    …
    querySelector: Function
    querySelectorAll: Function
}
|- NodePrototype
|- Object

所以你可以扩展它的原型并在你的应用程序中的 all XMLDocuments/上使用这些方法HTMLDocuments(但前提是你知道扩展 DOM 有什么问题)。

最重要的是,“猴子修补”Document使其可构造的危害是什么?

我不确定你会怎么做。覆盖它可能会损害每个期望它按上述方式工作的脚本(除非您修复了prototype新函数的属性)。在某些环境中,可能的Document属性window是不可写的,所以你可能会伤害自己。

于 2013-05-28T11:12:23.633 回答
1
  1. Document是全局作用域对象的原型定义,document意味着Document的原型与他的实例共享(document)。likeWindowwindow对象的原型定义。
  2. Document是本机原型对象,您不能创建它的实例,在创建页面时(再次,如窗口)只创建一个实例,就像单色调对象一样。
  3. 我不认为覆盖Document将是一个好习惯。

我的建议是为您的 API 使用命名空间并在您的 api 命名空间中创建 Document 和 HTMLElement 等,例如:

var api = {
    Document: { /* your implementation */ },
    HTMLElement: { /* your implementation */ }
    //...
};

var myDocument = new api.Document();

更重要的是,您可以继承真正的Document原型并在您自己的对象中使用它,如下所示:

api.Document = function(){ /* your implementation */ }
api.Document.prototype = Document.prototype;

var myDocument = new api.Document();

希望这是有帮助的,我理解你的问题......

于 2013-05-28T11:11:40.300 回答