源代码编译为机器可执行的二进制码。
编译过程中一般会识别你代码中的语法错误等问题,这个错误就叫编译时错误,做的一些检查也叫做编译时类型检查或者静态类型检查,因为静态就意味着代码还没有放到内存里去运行,只是把代码当做静态文本来扫描。
编译时代码还在硬盘中,而运行时代码跑起来了,已经运行在内存中去了。
对于编译型语言 java 来说:
java 的代码就是被编译为 .class 文件才能运行,这个编译过程就是编译时,运行 .class 文件就是运行时。
对于解释型语言 js 来说:
我们知道,在浏览器中 js 的解释器是 jscore、v8 等,我们在浏览器直接输入一些代码,就可以执行,并没有经过编译成某个文件。
所以我的理解是解释型语言是没有编译时,只有运行时。(当然有些人说 js 的变量提升等是预编译,但是我认为也不是传统意义上的编译时)
那我们常说的 js 编译是什么呢?
现代前端开发,我们都是使用 react、vue、webpack 等工具,其实就是把这些框架代码编译成了 js 代码,那么编译时其实是指的,webpack 等工具把 react、vue 编译为 js 的过程。运行时自然不用说,就是浏览器解释 js 代码的过程。
把树型结构的数据对象传入 render 函数,然后 render 函数渲染成 DOM 元素。
// 清空屏幕,确保网站有个 id="app" 的 dom
document.getElementById('app').innerHTML = ''
// 渲染 dom
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)
}
const node = {
tag: 'div', // tag代表标签名称
children: [ // children可以是一个数组,代表子节点
{
tag: 'h1',
children: 'hello' // children也可以是一段文本,代表文本子节点
}
]
}
const app = document.getElementById('app')
render(node, app)

这种通过 js 的方式生成页面就是运行时框架,可以看到书写非常的困难。
我们平常写 vue 是不是这样写的
<template>
<div>
<h1>helloh1>
div>
template>
假设上面的代码编译为下面的代码,直接在浏览器上可以运行
const div = document.createElement('div')
const h1 = document.createElement('h1')
h1.innerText = 'hello'
div.appendChild(h1)
document.body.appendChild(div)
但是很显然,vue 不是这样做的,我们可以在这个 在线网站 测试一下。

这段编译出来的代码,引入了一些乱七八糟的函数,传了一些乱七八糟的参数,很显然,这样的代码不是单纯的操作 DOM 的原生 JS,还包含了创建 VNode 、diff等操作。
由此,我们可以得出结论,Vue 是一个运行时 + 编译时的框架,在编译时把浏览器看不懂的代码转化为 JS 代码,在运行时创建虚拟 DOM,做 diff 对比,更新真实 DOM 等等操作。
举一些实例,比如 jQuery,就是一个运行时框架;Vue 或者 React,就比较折中,是运行时 + 编译时框架;