
JavaScript 引擎通常与浏览器或 Node.js 等资源丰富的环境绑定。但你是否想过,一个引擎仅需 10KB 的 RAM 就能跑起来?最近,由 QuickJS 作者 Fabrice Bellard 推出的 MicroQuickJS(也常写作 MQuickJS)正是这样一款面向极致资源受限环境的 JavaScript 引擎。
整个引擎(包括必要的 C 库)大约需要 100 kB 的 ROM(以 ARM Thumb-2 代码估算),其执行速度却能与它的“大哥”QuickJS 相媲美。
MicroQuickJS 的核心设计
MQuickJS 并非 QuickJS 的简单裁剪版。为了达到极低的内存消耗,它在内部机制上做了不少改动:
- 受限的 JavaScript 支持:它支持一个接近 ES5 标准的 JavaScript 子集,并且始终运行在严格模式下,禁用了一些容易出错或效率低下的语法结构。
- 跟踪式垃圾回收:采用更适合小内存环境的垃圾回收策略。
- 无 CPU 堆栈的虚拟机:进一步减少了运行时内存占用。
- UTF-8 编码字符串:字符串以 UTF-8 格式存储,更节省空间。

该项目在 GitHub 上采用 MIT 协议开源,作为一个新兴的嵌入式领域 开源实战 项目,已经获得了大量开发者的关注。
如何使用 MicroQuickJS
其命令行工具 mqjs 提供了多种运行模式,基本用法如下:
usage: mqjs [options] [file [args]]
-h --help list options
-e --eval EXPR evaluate EXPR
-i --interactive go to interactive mode
-I --include file include an additional file
-d --dump dump the memory usage stats
--memory-limit n limit the memory usage to ‘n’ bytes
--no-column no column number in debug information
-o FILE save the bytecode to FILE
-m32 force 32 bit bytecode output (use with -o)
-b --allow-bytecode allow bytecode in input file
1. 在极低内存限制下运行脚本
以下命令展示了如何仅用 10 KB 内存来运行一个 JavaScript 程序:
./mqjs --memory-limit 10k tests/mandelbrot.js
2. 编译为字节码
mqjs 支持将脚本编译为字节码并保存,便于部署到存储设备(如文件或 ROM):
./mqjs -o mandelbrot.bin tests/mandelbrot.js
3. 运行已编译的字节码
编译后的字节码可以像普通脚本一样直接执行:
./mqjs -b mandelbrot.bin
需要注意的是,字节码格式依赖于 CPU 的字节序和字长。在 64 位系统上,可以使用 -m32 选项生成兼容 32 位嵌入式系统的字节码。为了进一步节省空间,可以使用 --no-column 选项来移除调试信息中的列号(仅保留行号)。
需要注意的语法限制
由于 MQuickJS 严格遵循其 JavaScript 子集规范,开发者需要注意以下常见的限制:
- 数组行为严格:数组不能有空位(hole),也不允许在数组长度之外直接赋值来扩展数组。
// 数组不能有空位。不允许在数组末尾之后写入元素:
a = [];
a[0] = 1; // OK to extend the array length
a[10] = 2; // TypeError
- 受限的 eval 函数:不支持直接访问局部变量的
eval,只支持全局求值。
// 仅支持全局求值,因此无法访问或修改局部变量:
eval("1 + 2"); // forbidden
(1, eval)("1 + 2"); // OK
for…in 循环行为:for…in 循环默认只遍历对象自身的可枚举属性。为了保证行为一致,建议配合 hasOwnProperty 检查使用,或者更推荐使用 for…of 循环。
// `for...in`循环只遍历对象自身的属性,其应该与以下常见模式一起使用,以确保与标准 JavaScript 的行为一致
for(var prop in obj) {
if (obj.hasOwnProperty(prop)) {
…
}
}
// 始终优先使用 for 或 of,数组支持这种方式:
for(var prop of Object.keys(obj)) {
…
}
这些设计选择虽然带来了一些语法上的约束,但也使得代码在 MicroQuickJS 和其他标准 JavaScript 引擎间具有更好的可移植性。严格模式本身就是一个有效的 JavaScript 子集,因此遵循这些规则的代码在大多数环境下都能正常运行。
对于希望在单片机、物联网设备等资源极其有限的 C语言 环境中引入脚本能力的开发者来说,MicroQuickJS 提供了一个非常值得评估的轻量级选项。更多详细的技术规范和使用案例,可以参考其官方文档和代码仓库。
参考资料
如果你想深入探讨更多嵌入式开发或前端底层技术,欢迎到 云栈社区 与其他开发者交流分享。