这篇文章探讨了 Goja(https://github.com/dop251/goja),这是 Go 语言生态系统中的一个 JavaScript 运行时库。
背景:Goja 的需求
在项目中查询和操作大型数据集时遇到挑战,Go 语言虽高效但处理复杂 JSON 响应时繁琐。考虑过嵌入 Lua 脚本语言,但 Go 库在实现、版本等方面存在问题,最终选择 Goja,文中给出了对多个相关库的基准测试GitHub 仓库。
为什么选择 Goja
- 与 Go 结构体无缝集成:将 Go 结构体赋值到 JavaScript 运行时,Goja 可自动推断字段和方法,利用 Go 的反射能力调用字段的 getter 和 setter,实现 Go 和 JavaScript 之间强大而透明的交互。
示例展示
- 赋值和返回值:从 Go 向 JavaScript 运行时传递整数数组并过滤出偶数,展示了 Goja 无需显式类型注解即可遍历数组,过滤后将结果转换为 Go 的空接口切片
[]interface{}
,内部将整数表示为int64
。 - 结构体和方法调用:定义
Person
结构体,包含导出的Name
字段和未导出的age
字段及GetAge
方法,在 JavaScript 中可通过约定访问这些字段和方法,可通过FieldNameMapper
使 JavaScript 驼峰命名法与 Go 命名法转换。 - 异常处理:当 JavaScript 中出现异常时,Goja 使用标准 Go 错误处理来管理,错误值为
*goja.Exception
,提供关于 JavaScript 异常的信息,Goja 还可引发其他类型的异常,如*goja.StackOverflowError
等,可用于处理和报告。 - 使用 VM 池沙盒用户代码:注意到初始化 VM 耗时,利用
sync.Pool
重用对象,给出了包含全局函数add
的 VM 池示例,但存在全局命名空间被污染的问题,最终通过在匿名函数中执行用户代码避免“已声明”错误,经基准测试确认垃圾回收可有效清理。
- 赋值和返回值:从 Go 向 JavaScript 运行时传递整数数组并过滤出偶数,展示了 Goja 无需显式类型注解即可遍历数组,过滤后将结果转换为 Go 的空接口切片
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。