前面我们学习了react的简单的样例,也了解了react中两种创建虚拟DOM的方法,并对两种方法的特点,以及为什么要采用其中一种方法做了稍微深入的探讨。

经过前面的课程学习,我们对react是什么,react的用途是什么,以及react的特征都有了一点大致的了解。那么我们来回顾一下,前文中我们留下的一个问题,在第二课中我们曾经在在创建虚拟DOM那一步留下了一个问题

虚拟DOM到底是什么?

那么这节课,我们就稍微深入对比一下虚拟DOM和真实DOM

虚拟DOM是什么

前文我们就提出了这个问题,我想大家也都很疑惑,这个虚拟DOM的本质到底是什么呢?

是个函数吗?是字符串?再或者是个数组?

其实咱们这么猜也没用,那咱们上代码来验证一下看看。我们还是用之前的代码

  const VDOM = ( {/* 我们最疑惑的地方就是这个VDOM到底是个什么 */}
    <h1 id="title">
      <span>Hello, React</span>
    </h1>
  );
  ReactDOM.render(
    VDOM,
    document.getElementById("test")
  );
  {/* 当我们完全不了解一个东西的时候那么打印出来,就是最快捷的方法,所以我们:*/}
  console.log("虚拟DOM", VDOM);

然后我们到控制台看一下:

image-20211210130448196

这个格式,已以往的经验来看,这很明显是一个对象啊。

所以说我们疑惑了那么久的东西,其实就是js中的一个对象。而且从格式上来看,这个对象是一个普通对象,并不是数组对象或者函数对象。

但是这也仅仅只是我们用眼睛看出来的,但是我们并不是直观明确地有程序告诉我们这个虚拟DOM到底是不是一个普通对象。那么我们有没有办法来明确确定这个虚拟DOM到底是不是一个对象呢?

其实在js标准库函数中早已经为我们封装好了相应的方法供我们使用:

let VDOM = ...
console.log(typeof VDOM); // 打印出VDOM常量到底是什么类型
console.log(VDOM instanceof Object); // 打印出VDOM常量到底是不是一个对象

我们再来看一下执行之后的结果:

image-20211210131616579

这回就清晰了,浏览器的控制台中程序明确告诉我们,虚拟DOM的本质就是一个js普通对象

真实DOM是什么

经过前面的长篇大论,我们终于算是知道了困惑了我们好几个课时的虚拟DOM的本质到底是啥了,但是真实DOM有是个什么玩意儿呢?

孙子兵法有云:知己知彼,百战不殆。既然这一小节我们要对比虚拟DOM和真实DOM的本质区别,那么我们肯定要先知道这俩东西分别是什么。

前面我们已经知道了虚拟DOM的本质就是一个js对象。那么真实DOM的本质又是什么呢?

还是老方法,我们先打印一下:

但是可能有人要问了,我们哪里有真实DOM啊?来看一下代码的HTML部分:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Virtual DOM</title>
</head>
<body>
  <div id="test"></div>
</body>
</html>

之前我们在<body>标签里面就已经创建了一个容器了。我们来回忆一下,原生js怎么创建真实DOM?这个很简单啊,直接调用document.createElement方法就可以创建了。从方法字面意思上来理解,我们创建出来的真实DOMHTML层面具体表现为一个element,这也就代表这我们<body>标签中创建的这个容器,本质上就是创建了一个真实DOM

明白这一点,接下来的步骤就很明确了:

  1. 获取到这个DOM
  2. 赋值给一个变量
  3. 打印这个变量

就像下面这样操作:

const RDOM = document.getElementById("test");
console.log("真实DOM");

那我们来看一下结果:

image-20211210133612198

下面这一行打印出来的仿佛还真的就是一个element啊,但是依然还是之前的问题,我们看着它是一个element,但是它真的就是一个element吗?

还是老规矩,console.log(typeof RDOM)了;来看一下:

image-20211210140252840

诶?它也是个对象,但是在控制台却只能显示出这种element的形式,看不到这个对象拥有的属性。其实我们也还有办法,js也给我们提供了断点调试的功能:

const RDOM = document.getElementById("test");
console.log("真实DOM", RDOM);
console.log(typeof RDOM);
debugger;

现在再看一下:

image-20211210140902252

这下我们就可以看见真实DOM拥有那么多的属性。所以说通过以上的代码验证确定了,真实DOM的本质其实呢也是一个js对象。

虚拟DOM和真实DOM的区别

经过上面的验证,我们可以得出一个结论,虚拟DOM是一个js对象,真实DOM也是一个js对象。但是既然两个都是对象,他们的区别究竟在哪呢?

依然还是断点调试来看一下之前的虚拟DOM所拥有的属性:

image-20211210142149599

只有这么几个,和之前我们看得真实DOM所拥有的属性数量完全不是一个量级的。

所以我们可以说,虚拟DOM要更加轻量级。但是为什么要这么设计呢?因为虚拟DOM只是react内部在用,并不像要像真实DOM那样需要那么多的属性。但是最终react会将虚拟DOM映射成真实DOM呈现在页面上。

所以我们得出以下结论:

  1. 虚拟DOM比真实DOM要轻量级
  2. 虚拟DOM只在react内部使用
  3. 虚拟DOM必须要由react映射成真实DOM之后才能呈现在页面上

总结

通过这个课时的学习,我们知道:

  • 虚拟DOM和真实DOM本质上都是js对象,但是console.log打印真实DOM呈现出的是element
  • 虚拟DOM的属性数量或者API数量要远远少于真实DOM,所以虚拟DOM更加轻量级
  • 虚拟DOM只在react内部使用,必须由react映射成真实DOM才呢个呈现在页面上
  • 可以用typeof来获取某变量的类型
  • 可以用instanceof来判断某变量是不是某类型

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/virtual_real_dom/