• 「前端每日一问(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
  • 相关阅读:
    js生成cron表达式
    原生table控制tbody滚动而thead不滚动
    js记性
    oracle 多库表建立dblink查询
    java操作mysql数据库备份
    java 抓取网页的图片
    ZOJ 3485 Identification Number【模拟】【暴力】
    Codeforces 1037E Trips【图论】【dfs】
    Codeforces 1036C Classy Numbers 【数位dp】
    Codeforces 1036B Diagonal Walking v.2 【贪心】
  • 原文地址:https://www.cnblogs.com/konglxblog/p/16756724.html
Copyright © 2020-2023  润新知