初學 JavaScript 時,`document` 是最熟悉的全域物件;但當涉足 XML 處理、`createHTMLDocument` 等進階 API 時,`HTMLDocument`、`XMLDocument`、`Document` 及 `document` 之間的繼承與實例關係往往令人「捋不清」。本文為你梳理 DOM 核心體系的類別繼承鏈與實際應用場景。
W3C DOM 規範將 API 劃分為三個層級,理解這一點是釐清關係的鑰匙:
// 簡化繼承關係
Document (Core DOM 核心介面)
├── HTMLDocument (HTML DOM 擴充) ← 瀏覽器中 HTML 頁面的 document 實例類別
└── XMLDocument (XML DOM 擴充) ← responseXML、createDocument() 返回的實例類別
屬於 **DOMImplementation 介面** 的方法,用於**離屏建立一個全新的 HTML 文件物件**(`HTMLDocument` 實例),不關聯當前視窗。常用於模板渲染、Web Components Shadow DOM 初始化、或離屏解析 HTML 片段。MDN 文檔中歸類在 `DOMImplementation` 下,而非 `document` 直屬,故直接在 `document` 上查不到。
因為兩者皆繼承自 `Document` 介面,核心查詢 API(`getElementById`、`querySelector`、`createElement` 等)在 Core DOM 階段已定義,**多型** 使得同樣代碼能操作不同文件型別。
前者是 HTML 文件的**建構函式/類別**(暴露在全域供 `instanceof` 判斷),後者是 Core DOM 介面的建構函式(部分瀏覽器未暴露)。
console.log(document instanceof HTMLDocument); // true (HTML 頁面)
console.log(document instanceof XMLDocument); // false
console.log(document.constructor.name); // "HTMLDocument"
const xmlDoc = new DOMParser().parseFromString("<root/>", "application/xml");
console.log(xmlDoc instanceof XMLDocument); // true
console.log(xmlDoc instanceof HTMLDocument); // false
**Core DOM 定標準,HTML/XML DOM 做擴充,`document` 是具體實例。** 牢記這張圖譜,面對 `createHTMLDocument`、`responseXML`、跨文件節點導入(`importNode`/`adoptNode`)等進階場景時,就能精準判斷物件型別、選擇正確 API,不再「一下子全亂了」。