ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

现代 JavaScript 教程:document 对象在 DOM 层次结构中的位置——从 HTMLDocument 到 Node 的原型链溯源

现代 JavaScript 教程:document 对象在 DOM 层次结构中的位置——从 HTMLDocument 到 Node 的原型链溯源 文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载document是每个网页脚本最先接触的全局对象但它在 DOM 类层次结构中究竟属于哪一类它继承自Node、Element还是HTMLElement本篇以本仓库 4-where-document-in-hierarchy 练习 及其 官方解答 为核心结合 《节点属性type、tag 和 content》章节正文 的完整类层次知识讲解如何用constructor.name、__proto__原型链遍历、instanceof等手段自行定位document的类归属并掌握不用查规范、手动在控制台里验证继承关系的通用排查技巧。读完你将能准确说出document的完整继承链并理解Document与HTMLDocument这两个类在规范与浏览器实现中的微妙关系。任务原题document 属于哪一类在 task.md 中本教程给出了一道自测题importance: 4document属于哪一类它位于 DOM 层次结构hierarchy中的什么位置它继承自Node还是Element或者可能是HTMLElement表面上看document与document.body、document.querySelector(div)返回的元素一样都是节点但document并不对应任何 HTML 标签它既不是Element也不是HTMLElement——它在 DOM 树中扮演的是整份文档的角色。要得到确切答案不必翻阅规范原文直接用 JavaScript 本身就能把它的类身份逼问出来。第一步直接读出对象的类名最直接的验证方式是输出document本身。浏览器对 DOM 对象的toString会给出[object 类名]的形式alert(document); // [object HTMLDocument]更规范的做法是通过constructor属性读取类名——每个对象都持有对其构造函数的引用constructor.name就是构造函数的名称alert(document.constructor.name); // HTMLDocument因此document是HTMLDocument类的一个实例而不是Node或Element的直接实例。这两个输出已经回答了属于哪一类的问题但位于层次结构的什么位置还需要继续向上追溯。第二步沿原型链向上遍历类的方法存放在构造函数constructor的prototype中例如HTMLDocument.prototype上挂着文档专用的方法同时prototype对象内部又持有对构造函数的反向引用可用constructor取回alert(HTMLDocument.prototype.constructor HTMLDocument); // true利用这一性质我们可以在任意一个类对象上通过constructor.name拿到类名再通过__proto__跳到父类的prototype一路向上直到顶层类Nodealert(HTMLDocument.prototype.constructor.name); // HTMLDocument alert(HTMLDocument.prototype.__proto__.constructor.name); // Document alert(HTMLDocument.prototype.__proto__.__proto__.constructor.name); // Node结果清晰地给出了继承链document → HTMLDocument → Document → NodeHTMLDocument.prototype的原型是Document.prototype而Document.prototype的原型又是Node.prototype。document的实例方法就是这条链上每一层prototype叠加的结果——这就是它位于 DOM 层次结构中的确切位置。提示__proto__是浏览器长期支持的遗留访问器。在需要严谨的现代代码中可以用Object.getPrototypeOf(HTMLDocument.prototype)等价的Object.getPrototypeOf调用来替代两者的溯源结果一致。第三步用 console.dir 可视化验证除了代码层面的遍历开发者工具还提供了图形化验证方式。在控制台执行console.dir(document);然后逐层展开__proto__可以看到每一层原型对象的constructor名称依次为HTMLDocument、Document、Node、EventTarget……控制台展示的名称正是从各层constructor内部读取出来的与代码遍历的结果完全对应。需要留意的是console.dir与console.log对 DOM 对象的差异详见 article.md 的说明框console.log(elem)显示元素在页面中的 DOM 树console.dir(elem)把元素当作 JavaScript 对象展开非常适合探查其原型与属性。全景DOM 节点类的完整层次结构document的归属只是整张 DOM 类层次图的一个分支。根据 article.md 的DOM 节点类一节所有 DOM 节点属于相应的内建类并形成以EventTarget为根的单一路径继承结构本仓库的 dom-class-hierarchy.svg 给出了完整图示各层类的职责如下EventTarget—— 一切 DOM 节点的根抽象类对象从不被直接创建作用是让所有 DOM 节点统一支持事件机制Node—— 同为抽象类提供树的核心功能parentNode、nextSibling、childNodes等均为 getterDocument / HTMLDocument—— 代表整份文档全局变量document即此类的实例充当 DOM 的入口。由于历史原因HTMLDocument继承自Document尽管最新规范对此不再强制规定CharacterData—— 抽象类派生出Text元素内部文本与Comment注释Element—— 元素的基础类提供nextElementSibling、children、getElementsByTagName、querySelector等元素级导航与搜索能力它进一步派生出SVGElement、XMLElement和HTMLElementHTMLElement—— 所有 HTML 元素的基础类又被HTMLInputElementinput、HTMLBodyElementbody、HTMLAnchorElementa等更具体的类继承没有专属属性的元素如span、section、article直接就是HTMLElement的实例。把document放回这张图里它的完整继承链实际是document → HTMLDocument → Document → Node → EventTarget → Object最底层还有普通对象Object因此hasOwnProperty这类普通对象方法同样可用。可以看到Element与Document在Node之下分属两个不同分支——这正是document既不是Element也不是HTMLElement的结构性原因。交叉验证instanceof、nodeType 与 nodeName除了原型链遍历article.md 还提供了多种互补的验证手段。instanceof 检查继承关系。以document.bodyHTMLBodyElement实例为例它对链上每一层类都返回truealert(document.body instanceof HTMLBodyElement ); // true alert(document.body instanceof HTMLElement ); // true alert(document.body instanceof Element ); // true alert(document.body instanceof Node ); // true alert(document.body instanceof EventTarget ); // true对document做同样的检查它会通过Node与EventTarget的验证但会失败于Element/HTMLElement——再次印证它不在元素分支上。nodeType 数值判型。nodeType是只读的数值型属性元素为1文本节点为3而document对象为9alert(document.nodeType); // 9nodeName 与 tagName 的差异。tagName仅由Element类提供因此对document返回undefinednodeName对任意Node都有效document的值为#documentalert(document.tagName); // undefineddocument 不是元素 alert(document.nodeName); // #documentnodeName返回#document而tagName为undefined是从属性层面证明document 不是元素的直观证据。常见误区与注意点不要把Document与HTMLDocument混为一谈Document是通用文档接口HTMLDocument是其针对 HTML 文档的历史性扩展类document的实例类实际是HTMLDocumentconstructor.name可直接确认。现代规范对二者的继承关系不再强制但主流浏览器的原型链仍保持HTMLDocument → Document → Node本仓库的解答也是按此给出。__proto__与Object.getPrototypeOf__proto__是便捷的访问器适合在控制台快速溯源严谨的库代码应优先使用Object.getPrototypeOf()避免依赖遗留属性。实例方法来自继承链叠加document能调用querySelector、getElementById来自Document/HTMLDocument层以及parentNode、childNodes来自Node层这正是类层次结构的意义所在——给定节点的全部属性和方法是整条继承链的结果。Element 分支与文档分支在 Node 处分叉判断一个对象是不是元素时优先用instanceof Element而非instanceof Node——因为document、文本节点、注释都会通过Node检查却都不是元素。总结回到任务原题document是HTMLDocument类的一个实例位于 DOM 层次结构Node之下的文档分支完整继承链为HTMLDocument → Document → Node → EventTarget它不继承自Element更不是HTMLElement。验证路径可以归纳为三步无需查阅规范alert(document.constructor.name)直接读出实例类HTMLDocument沿HTMLDocument.prototype.__proto__逐层用constructor.name打印得到Document、Node用console.dir(document)展开原型链做图形化复核或用instanceof、nodeType 9、nodeName #document从多个角度交叉确认。这套类名 原型链 控制台的排查手法不仅适用于document也适用于任意 DOM 节点例如document.body.constructor.name会得到HTMLBodyElement是深入理解 DOM 节点类 体系的通用技能。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐document 在 DOM 类层次结构中的位置从 HTMLDocument 到 Node 的原型链溯源zh.javascript.info 实战解析document 在 DOM 类层次结构中的位置从 HTMLDocument 到 Node 的原型链溯源zh.javascript.info 实战解析 d文档教程前端document 在 DOM 类继承体系中的位置从 HTMLDocument 到 Node 的原型链溯源document 在 DOM 类继承体系中的位置从 HTMLDocument 到 Node 的原型链溯源 本文基于 Modern JavaScript Tut文档/教程前端JavaScript 教程document 在 DOM 类层级中的位置详解HTMLDocument / Document / NodeJavaScript 教程document 在 DOM 类层级中的位置详解HTMLDocument / Document / Node document文档/教程前端上一篇3分钟集成FLEX调试神器Carthage配置iOS应用内调试工具完全指南下一篇突破TTS效率瓶颈Tortoise-TTS重复文本缓存机制全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表