编程 Goja,这是Golang生态系统中的一个JavaScript运行时库

2024-11-19 07:59:21 +0800 CST views 610

探索 Goja:Golang 中的 JavaScript 运行时

本文介绍了 Goja,这是 Golang 生态系统中的一个 JavaScript 运行时库。作为一个嵌入式 JavaScript 引擎,Goja 可以在 Go 应用程序中运行 JavaScript 代码,并且与 Go 结构体无缝集成。Goja 为处理复杂数据、脚本化任务提供了高效的解决方案,尤其适合在 Golang 项目中引入动态执行逻辑。

背景:Goja 的需求

在项目中操作和查询大型数据集时,尽管 Go 语言在性能上具有优势,但在处理复杂的 JSON 响应时,编写 Go 代码显得繁琐冗长。嵌入式脚本语言可以简化这些任务,因此我们探索了 Go 中的各种嵌入式语言选项,包括 LuaExprV8Starlark。最终,Goja 凭借其与 Go 结构体的无缝集成成为最有希望的候选者。

为什么选择 Goja?

Goja 最大的优势在于它可以自动推断 Go 结构体的字段和方法,使得这些内容在 JavaScript 中直接可用,无需复杂的桥接层。通过 Go 的反射机制,Goja 能够自动访问 Go 结构体的 getter 和 setter,提供了强大而透明的 Go 和 JavaScript 交互。

赋值和返回值

以下示例展示了如何在 Goja 中传递和处理数组,并过滤出其中的偶数值:

package main

import (
	"fmt"
	"github.com/dop251/goja"
)

func main() {
	vm := goja.New()

	// 从 1 到 100 传递一个整数数组
	values := []int{}
	for i := 1; i <= 100; i++ {
		values = append(values, i)
	}

	// 定义 JavaScript 代码以过滤偶数值
	script := `
		values.filter((x) => {
			return x % 2 === 0;
		})
	`

	// 在 JavaScript 运行时中设置数组
	vm.Set("values", values)

	// 运行脚本
	result, err := vm.RunString(script)
	if err != nil {
		panic(err)
	}

	// 将结果转换回 Go 的空接口切片
	filteredValues := result.Export().([]interface{})

	fmt.Println(filteredValues)
	// 输出:[2, 4, 6, 8, ... 100]
}

结构体和方法调用

Goja 可以直接与 Go 结构体交互,如下所示:

package main

import (
	"fmt"
	"github.com/dop251/goja"
)

type Person struct {
	Name string
	age  int
}

// 获取年龄的方法
func (p *Person) GetAge() int {
	return p.age
}

func main() {
	vm := goja.New()

	person := &Person{Name: "John Doe", age: 30}
	vm.Set("person", person)

	// JavaScript 代码访问结构体的字段和方法
	script := `
		const name = person.Name;
		const age = person.GetAge();
		name + " is " + age + " years old.";
	`

	result, err := vm.RunString(script)
	if err != nil {
		panic(err)
	}

	fmt.Println(result.String()) // 输出:John Doe is 30 years old.
}

异常处理

Goja 提供了异常处理机制,以下是一个处理 JavaScript 中除以零错误的示例:

package main

import (
	"errors"
	"fmt"
	"github.com/dop251/goja"
)

const script = `const a = 1n / 0n;`

func main() {
	vm := goja.New()

	_, err := vm.RunString(script)
	if err != nil {
		var exception *goja.Exception
		if errors.As(err, &exception) {
			fmt.Printf("JavaScript error: %s\n", exception.Error())
		}
	}
}

使用 VM 池优化性能

为了避免频繁初始化 VM,可以使用 sync.Pool 来复用 Goja 虚拟机,减少创建 VM 的开销:

package main

import (
	"fmt"
	"sync"
	"github.com/dop251/goja"
)

var vmPool = sync.Pool{
	New: func() interface{} {
		vm := goja.New()
		vm.Set("add", func(a, b int) int { return a + b })
		return vm
	},
}

func main() {
	vm := vmPool.Get().(*goja.Runtime)
	defer vmPool.Put(vm)

	script := `const result = add(5, 10); result;`

	value, err := vm.RunString(script)
	if err != nil {
		panic(err)
	}

	fmt.Println("Result:", value.Export()) // 输出:15
}

结论

Goja 是 Go 生态系统中灵活、性能优越的 JavaScript 运行时库,通过无缝的 Go 结构体集成和强大的异常处理机制,极大地简化了复杂数据和脚本任务的处理流程。Goja 使开发者能够在 Golang 项目中使用动态脚本语言,而不牺牲性能。

参考资料

这篇文章深入介绍了 Goja 的使用场景、优势以及在 Golang 中嵌入 JavaScript 的最佳实践,并展示了多个示例代码,帮助开发者快速掌握该库的应用。

复制全文 生成海报 编程 Golang JavaScript 开发工具 性能优化

推荐文章

Golang 随机公平库 satmihir/fair
2024-11-19 03:28:37 +0800 CST
PHP 代码功能与使用说明
2024-11-18 23:08:44 +0800 CST
Shell 里给变量赋值为多行文本
2024-11-18 20:25:45 +0800 CST
CSS 奇技淫巧
2024-11-19 08:34:21 +0800 CST
pycm:一个强大的混淆矩阵库
2024-11-18 16:17:54 +0800 CST
55个常用的JavaScript代码段
2024-11-18 22:38:45 +0800 CST
【SQL注入】关于GORM的SQL注入问题
2024-11-19 06:54:57 +0800 CST
mysql 优化指南
2024-11-18 21:01:24 +0800 CST
MySQL 优化利剑 EXPLAIN
2024-11-19 00:43:21 +0800 CST
windon安装beego框架记录
2024-11-19 09:55:33 +0800 CST
三种高效获取图标资源的平台
2024-11-18 18:18:19 +0800 CST
Vue3的虚拟DOM是如何提高性能的?
2024-11-18 22:12:20 +0800 CST
解决python “No module named pip”
2024-11-18 11:49:18 +0800 CST
如何优化网页的 SEO 架构
2024-11-18 14:32:08 +0800 CST
Vue 中如何处理跨组件通信?
2024-11-17 15:59:54 +0800 CST
MySQL 主从同步一致性详解
2024-11-19 02:49:19 +0800 CST
详解 Nginx 的 `sub_filter` 指令
2024-11-19 02:09:49 +0800 CST
Mysql允许外网访问详细流程
2024-11-17 05:03:26 +0800 CST
前端开发中常用的设计模式
2024-11-19 07:38:07 +0800 CST
Golang Select 的使用及基本实现
2024-11-18 13:48:21 +0800 CST
MySQL数据库的36条军规
2024-11-18 16:46:25 +0800 CST
动态渐变背景
2024-11-19 01:49:50 +0800 CST
开发外贸客户的推荐网站
2024-11-17 04:44:05 +0800 CST
Plyr.js 播放器介绍
2024-11-18 12:39:35 +0800 CST
介绍25个常用的正则表达式
2024-11-18 12:43:00 +0800 CST
Vue中如何处理异步更新DOM?
2024-11-18 22:38:53 +0800 CST
程序员茄子在线接单