「前端每日一问(51)」什么是运行时和编译时?

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

本题难度:⭐ ⭐

本题类型:综合题、开放问题

答:简单来说,运行时是指一段代码,直接扔进浏览器里能运行,编译时是指一段代码不能直接在浏览器里跑,需要先经过编译器编译,再放到浏览器里才能运行。

运行时

比如:提供一个 render 函数,接收两个参数,一个是具有一定规范的树型结构的数据对象,一个是要挂载的节点。

开发者把树型结构的数据对象传入 render 函数,然后 render 函数根据改对象递归地将数据渲染成 DOM 元素。

这个树型结构须按照一定的规范,形状如下:

const node = {
  tag: 'div', // tag代表标签名称
  children: [ // children可以是一个数组,代表子节点
    {
      tag: 'h1',
      children: 'hello' // children也可以是一段文本,代表文本子节点
    }
  ]
}
复制代码

render 函数的实现如下:

function render (node, root) {
  const el = document.createElement(node.tag)
  if (typeof node.children === 'string') {
    const text = document.createTextNode(node.children)
    el.appendChild(text)
  }
  if (Array.isArray(node.children)) {
    node.children.forEach(child => render(child, el)) // 递归地处理节点的渲染
  }
  root.appendChild(el)
}
复制代码

执行 render 函数,就可以生成页面元素,如下图:

image.png

这种使用纯 JS 的方式生成页面内容就是运行时框架,很显然,在开发者层面,通过这种方式书写代码一定会非常痛苦。

所以在 Vue 里面,我们写的不是类似上文的代码,而是写 template 模板。

编译时

比如,下面这段代码,浏览器里不能直接跑,需要先编译成 JS ,才能在浏览器里运行。

<template>
  <div>
    <h1>hello</h1>
  </div>
</template>
复制代码

假设上面的 html 代码,直接编译成命令式的代码,就是编译时代码,如下所示:

const div = document.createElement('div')
const h1 = document.createElement('h1')
h1.innerText = 'hello'
div.appendChild(h1)
document.body.appendChild(div)
复制代码

开发者只提供 html 模板代码,在框架内部分析开发者提供的代码,编译成命令式的代码,再渲染到页面上。

但是很显然,Vue 不是这么做的,我们在这个 在线网址 里去测试一下:

<template>
  <div>
    <h1>hello</h1>
  </div>
</template>
复制代码

这段 html 代码在 Vue 内部被编译成下面这段代码。

import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("template", null, [
    _createElementVNode("div", null, [
      _createElementVNode("h1", null, "hello")
    ])
  ]))
}
复制代码

这段编译出来的代码,引入了一些乱七八糟的函数,传了一些乱七八糟的参数,很显然,这样的代码不是单纯的操作 DOM 的原生 JS,还包含了创建 VNode 、diff等操作。

由此,我们可以得出结论,Vue 是一个运行时 + 编译时的框架,在编译时把浏览器看不懂的代码转化为 JS 代码,在运行时创建虚拟 DOM,做 diff 对比,更新真实 DOM 等等操作。

举一些实例,比如 jQuery,就是一个运行时框架;Vue 或者 React,就比较折中,是运行时 + 编译时框架;而 Svelte ,就是一个编译时框架。

结尾

阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

你也可以关注《前端每日一问》这个专栏,防止失联哦~

我是阿林,输出洞见技术,再会!

本文参考:Vue.js设计与实现

上一篇:

「前端每日一问(50)」虚拟 DOM 和原生 JS 究竟谁性能更好?

下一篇:

「前端每日一问(52)」计算斐波那契数

来源:https://juejin.cn/post/7086456669978230820
posted @ 2022-10-05 23:03  程序员小明1024  阅读(123)  评论(0编辑  收藏  举报