美文网首页前端开发那些事儿
一篇深度剖析DOM元素真实面目

一篇深度剖析DOM元素真实面目

作者: 深度剖析JavaScript | 来源:发表于2020-08-15 06:21 被阅读0次

我理解的DOM文档对象模型,说白了就是一系列用于表示文档的东西,这些东西本质是对象,这些对象表示了文档的各个不同部位。

例如DOM中DOM对象也叫DOM节点,节点有分document节点、元素节点、属性节点、文本节点、注释节点等,分别表示文档中的整个文档、某个元素、某个元素的属性、某个元素里面的文本、某个元素里面的注释等。

节点对象中定义了一系列的属性和方法,这些属性和方法跟我们平时自己写的js并没有什么不同,只不过这一系列的接口由浏览器厂商定义,用于更好、更方便的表示和操作文档。

而DOM本质就是这一系列对象的继承关系,由于这继承关系复杂,导致我们不好理解。特写这边文章梳理一下,看看DOM里面到底有什么鬼!

那从哪里开始看呢?

没有思路的话,就以我们熟悉的document为例子吧

document对象事代表整个HTML文档的,我们看看它的原型及它是谁构造出来的


可以看到document对象是由构造函数HTMLDocument(){}构造出来的,该构造函数的原型是HTMLDocument{}
document可以继承其原型HTMLDocument{}上的属性和方法
不妨一探究竟,看看原型里面到底定义里什么,看有没有我们眼熟的。
发现HTMLDecument.prototype上居然定义了怎么多属性和方法,我画了一下上篇文章有讲到的一些用于遍历节点的方法。
看看目前的关系:

接着,我们来看看

  1. 构造函数HTMLDocument(){}
  2. 原型对象HTMLDocument{}
首先,我们来查看构造函数HTMLDocument(){}的原型和构造函数

发现

  1. HTMLDocument(){}的构造函数Function(){},我们知道所有方法都是都new Function产生的,所以这里已经到尽头,无需说再往下看Function(){}
  2. HTMLDocument(){}作为对象时,它的原型__proto__是Document(){};而它作为function时,原型指向是HTMLDocument:{},这里别搞混了。
    接着来看,原型对象HTMLDocument{}即document.__proto__ image.png

发现
document.__proto__的构造函数是HTMLDocument(){};这就是上面一直说的那个HTMLDocument(){}。
这点其实很容易理解,构造函数上有个prototype属性指向原型,原型有个属性constructor指向该构造函数

还发现:
document.__proto__ 往上,即:document.__proto__.__proto__是继承自Document{}
我们在来看看这个原型对象里面有什么鬼:


我去,这都是什么鬼
有空可以点开认真看看,其实我想主要表达的是:为什么document能使用getElementsByClassName这些东西,其实就是因为它顺着它的原型链往上找,找到这里定义的getElementsByClassName方法。
我在这里小结一下吧:
1. document并非由Document(){},而是由HTMLDocument(){}构造
2. document的原型是HTMLDocument:{},这个HTMLDocument对象里面定义了很多方法和属性,如:
children、childNodes、lastChild、lastElementChild、nextSibing、nodeName、nodeType、nodeValue、parentElement、parentNoded等等
3. document的原型的原型是Document:{}。这个大的Document上方法和属性巨多,忍不住想说几个方法:
crateElement()、crateTextNode()、crateAttribute()、getElementById()、getElementsByClassName()、getElementsByName()、getElementsByTagName()、querySelector()、querySelectorAll()等等...

到这里可以在看下我们的图,捋一下他们的关系:


看到这里有心细的同学肯定会想Document:{}和Document(){}是不是有什么关系呢?
你猜的没错,Document:{}就是这个Document(){}构造出来的,不信我,那咱们试试:


哈哈!
go on!
我再来看Document:{}的原型是谁
为了足够深入,我们还是得看看它指向的Node:{}里面又有些什么(别怕麻烦,一次搞清楚了,下次再也不怕了)

我们发现Node里面也有一些的方法和属性,常见的如:hasChildNodes()
另外有好多数值,视乎是nodeType;而且它还有原型指向EventTarget:{}
为了不乱,先画下图吧

那我先看EventTarget:{}吧,我们就是想看看document最终继承自谁,还没完没了了不成。
看看EventTarget:{}里面的东西:


这下开心了,终于看到了想看到的东西,就是我们最最熟悉的Object了
另外还发现原来给元素添加和移除事件的方法addEventListener()、removeEventListener()也定义在EventTarget:{}里头了
试试Object上面还有吗?

Object就到顶了,再上就会返回null。那这里就不用再看了。
document的原型链

接着我们回到图看下先


我们先看看EventTarget:{}和Object:{}分别是谁构造出来的吧:
发现EventTarget:{}和Object:{}分别是由对应的构造函数EventTarget(){}和Object(){}构造出来的。

接着在来看Document(){}、EventTarget(){}、Object(){}是谁构建出来的
发现所有的function都是由function Function(){}构建出来的

那Function的构造函数呢?也会返回function Function(){}!!!
js中一切皆是对象,我们看看Function(){}作为对象时,它的原型指向是谁
第一层指向匿名function(){},第二层就直接指向Object了。

其中我这里可以看到一个规律:
一般原型对象(非原型链首尾对象)都是两进两出,即:
两进是别的对象__proto__指向我和构造函数prototype指向我;
两出是我的属性constructor和__proto__
先完善这点


再看,一般的方法是两进三出:
两进是我生产的对象的constructor指向我,以及我的原型的constructor指向我。(这里大部分没讲到自己生产的对象,所以只有一个原型指向我)
三出是:1 我的constructor指向Function,2我作为function我的prototype指向谁,3我作为对象时我的__proto__指向谁
规律非绝对!
根据上面说的规则再来完善,另外发现上面漏了一个Node:{},现在补上,对不住大家了哈:
我们发现:
基本所有的对象都是通过构造函数产生的,而所有的构造函数都是Function产生的
基本所有对象的原型都是最终继承自Object。

到这里其实也还没讲完,这是一个思路!这只是以document为例子讲的。因为DOM对象太多,他们继承的情况有所不同,大家可以根据这个思路将你想了解的元素类型,通过这个方式更加深入了解到其里面本来面目,让学习学的更加透彻!!

相关文章

  • 一篇深度剖析DOM元素真实面目

    我理解的DOM文档对象模型,说白了就是一系列用于表示文档的东西,这些东西本质是对象,这些对象表示了文档的各个不同部...

  • 2019-12-30 文章索引

    2019.12.301、深度剖析:如何实现一个 Virtual DOM 算法https://github.com/...

  • Vue虚拟Dom与diff算法原理

    什么是虚拟DOM? 真实的元素节点: 为什么使用虚拟DOM? 虚拟DOM的作用是什么? 虚拟DOM和真实DOM的区...

  • React基础篇之虚拟DOM

    Hello World JS创建虚拟DOM JSX创建虚拟DOM 虚拟DOM与真实DOM 下一篇:React基础篇...

  • Virtual DOM(虚拟DOM)

    一、概念 Virtual DOM 是一个映射真实DOM的Javascript对象,如果需要改变任何元素的状...

  • react基础语法1:render函数

    react-dom: 把jsx语法(react独有的语法)转换为真实的dom元素 最终渲染的index.html文...

  • 虚拟DOM

    原文:深入剖析:Vue核心之虚拟DOM 真实DOM和其解析流程 所有的浏览器渲染引擎工作流程大致分为5步:创建 D...

  • 虚拟dom原理

    声明:本文copy自深度剖析:如何实现一个 Virtual DOM 算法-戴嘉华,留做记录已做日后温习 目录: 1...

  • virtual dom 原理

    声明:本文copy自深度剖析:如何实现一个 Virtual DOM 算法-戴嘉华,留做记录已做日后温习 目录: 1...

  • Canvas弹幕实现

    anvas原生实现直播视频弹幕效果。 原文链接 上一篇中用动态创建DOM元素实现弹幕效果,好处是可以在DOM元素上...

网友评论

    本文标题:一篇深度剖析DOM元素真实面目

    本文链接:https://www.haomeiwen.com/subject/adqgdktx.html