goscript

package module
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2022 License: Apache-2.0 Imports: 49 Imported by: 0

README

goscript

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	SymHasInstance        = newSymbol(asciiString("Symbol.hasInstance"))
	SymIsConcatSpreadable = newSymbol(asciiString("Symbol.isConcatSpreadable"))
	SymIterator           = newSymbol(asciiString("Symbol.iterator"))
	SymMatch              = newSymbol(asciiString("Symbol.match"))
	SymMatchAll           = newSymbol(asciiString("Symbol.matchAll"))
	SymReplace            = newSymbol(asciiString("Symbol.replace"))
	SymSearch             = newSymbol(asciiString("Symbol.search"))
	SymSpecies            = newSymbol(asciiString("Symbol.species"))
	SymSplit              = newSymbol(asciiString("Symbol.split"))
	SymToPrimitive        = newSymbol(asciiString("Symbol.toPrimitive"))
	SymToStringTag        = newSymbol(asciiString("Symbol.toStringTag"))
	SymUnscopables        = newSymbol(asciiString("Symbol.unscopables"))
)
View Source
var (
	InvalidRuneError = errors.New("invalid rune")
)

Functions

func IsInfinity

func IsInfinity(v Value) bool

IsInfinity 如果 Value 是正负无穷大,则返回 true

func IsNaN

func IsNaN(v Value) bool

IsNaN 如果 Value 是 NaN,则返回 true

func IsNull

func IsNull(v Value) bool

IsNull 如果 Value 的值是 null,则返回 true

func IsUndefined

func IsUndefined(v Value) bool

IsUndefined 如果提供的值是未定义的,则返回 true 注意,它检查的是真正的未定义,而不是全局对象的'未定义'属性

func Parse

func Parse(name, src string, options ...parser.Option) (prg *jast.Program, err error)

Parse 接收一个源字符串并产生一个解析的 AST。如果你想向解析器传递选项,请使用此函数 例如:

p, err := Parse("test.js", "var a = true", parser.WithDisableSourceMaps)
if err != nil { /* ... */ }
prg, err := CompileAST(p, true)
// ...

否则就使用 Compile,它结合了这两个步骤

Types

type ArrayBuffer

type ArrayBuffer struct {
	// contains filtered or unexported fields
}

ArrayBuffer 是 ECMAScript ArrayBuffer 的 Go 封装器。对其调用 Runtime.ToValue() 将返回底层 ArrayBuffer 在 ECMAScript ArrayBuffer 上调用 Export() 会返回一个封装器 使用 Runtime.NewArrayBuffer([]byte) 来创建它

func (ArrayBuffer) Bytes

func (a ArrayBuffer) Bytes() []byte

Bytes 返回这个 ArrayBuffer 的 []byte 内容 对于已脱离的 ArrayBuffers 返回 nil

func (ArrayBuffer) Detach

func (a ArrayBuffer) Detach() bool

Detach 脱离ArrayBuffer,在这之后,底层的 []byte 将变得没有参考价值,任何试图使用这个 ArrayBuffer 的行为都会导致 TypeError 如果已经脱离,返回false,否则返回true 注意,这个方法只能从拥有 Runtime 协程中调用,不能被多个协程同时调用

func (ArrayBuffer) Detached

func (a ArrayBuffer) Detached() bool

type Callable

type Callable func(this Value, args ...Value) (Value, error)

Callable 代表一个可以从 Go 中调用的 Javascript函数

func AssertFunction

func AssertFunction(v Value) (Callable, bool)
Example
vm := New()
_, err := vm.RunString(`
	function sum(a, b) {
		return a+b;
	}
	`)
if err != nil {
	panic(err)
}
sum, ok := AssertFunction(vm.Get("sum"))
if !ok {
	panic("Not a function")
}

res, err := sum(Undefined(), vm.ToValue(40), vm.ToValue(2))
if err != nil {
	panic(err)
}
fmt.Println(res)
// 输出: 42
Output:

type CompilerError

type CompilerError struct {
	Message string
	File    *file.File
	Offset  int
}

type CompilerReferenceError

type CompilerReferenceError struct {
	CompilerError
}

func (*CompilerReferenceError) Error

func (e *CompilerReferenceError) Error() string

type CompilerSyntaxError

type CompilerSyntaxError struct {
	CompilerError
}

func (*CompilerSyntaxError) Error

func (e *CompilerSyntaxError) Error() string

type Constructor

type Constructor func(newTarget *Object, args ...Value) (*Object, error)

Constructor 构造函数是一个可以用来调用构造函数的类型。第一个参数(newTarget)可以是 nil,将其设置为构造函数本身

func AssertConstructor

func AssertConstructor(v Value) (Constructor, bool)
Example
vm := New()
res, err := vm.RunString(`
		(class C {
			constructor(x) {
				this.x = x;
			}
		})
	`)
if err != nil {
	panic(err)
}
if ctor, ok := AssertConstructor(res); ok {
	obj, err := ctor(nil, vm.ToValue("Test"))
	if err != nil {
		panic(err)
	}
	fmt.Print(obj.Get("x"))
} else {
	panic("Not a constructor")
}
// 输出: Test
Output:

type ConstructorCall

type ConstructorCall struct {
	This      *Object
	Arguments []Value
	NewTarget *Object
}

func (ConstructorCall) Argument

func (f ConstructorCall) Argument(idx int) Value

type DynamicArray

type DynamicArray interface {
	Len() int                    // 返回当前数组的长度
	Get(idx int) Value           // 在索引 idx 处获取一个 item。idx 可以是任何整数,可以是负数,也可以是超过当前长度的
	Set(idx int, val Value) bool // 在索引 idx 处设置一个 item。idx 可以是任何整数,可以是负数,也可以超过当前的长度。当它超出长度时,预期的行为是数组的长度会增加以容纳该 item。数组中的新增部分的所有元素将会被预置为零值
	SetLen(int) bool             // 变更数组的长度,如果长度增加,数组中的新增部分的所有元素将会被预置为零
}

DynamicArray 是一个接口,代表一个动态数组对象的处理程序。这样的对象可以用 Runtime.NewDynamicArray() 方法创建 任何可以解析为 int 值的整型属性 key 或字符串属性 key(包括负数)都被视为索引,并传递给 DynamicArray 的捕获方法 注意这与普通的 ECMAScript 数组不同,后者只支持 2^32-1 以内的正数索引 动态数组不能是稀疏的,即 hasOwnProperty(num) 对于 num >= 0 && num < Len(),将返回 true 删除这样的属性等同于将其设置为 undefined, 这产生了一个轻微的特殊性,因为 hasOwnProperty() 即使在删除之后,仍然会返回 true 请注意,Runtime.ToValue() 对 DynamicArray 没有任何特殊处理。创建一个动态数组的唯一方法是使用 Runtime.NewDynamicArray()方法 这样做是故意的,以避免在这个接口改变时出现不预期且无声的代码中断

type DynamicObject

type DynamicObject interface {
	Get(key string) Value           // 为 key 获取一个属性值。如果该属性不存在,则返回 nil
	Set(key string, val Value) bool // 为 key 设置一个属性值。如果成功返回 true,否则返回 false
	Has(key string) bool            // 当指定 key 的属性存在时,返回 true
	Delete(key string) bool         // 删除以 key 为名的属性,成功时返回 true(包括不存在的属性)
	Keys() []string                 // 返回一个所有现有 key 的列表。没有重复检查,也没有确定顺序是否符合 https://262.ecma-international.org/#sec-ordinaryownpropertykeys
}

DynamicObject 是一个接口,代表一个动态对象的处理程序。这样的对象可以使用 Runtime.NewDynamicObject() 方法创建 请注意,Runtime.ToValue() 对 DynamicObject 没有任何特殊处理。创建一个动态对象的唯一方法是使用 Runtime.NewDynamicObject() 方法 这样做是故意的,以避免在这个接口改变时出现不预期且无声的代码中断

type Error

type Error struct {
	Err    error
	Stderr string
}

func (Error) Error

func (e Error) Error() string

type Exception

type Exception struct {
	// contains filtered or unexported fields
}

func (*Exception) Error

func (e *Exception) Error() string

func (*Exception) String

func (e *Exception) String() string

func (*Exception) Value

func (e *Exception) Value() Value

type FieldNameMapper

type FieldNameMapper interface {
	// FieldName 返回给定类型的结权字段的 Javascript 名称
	// 如果这个方法返回空串,给定字段将被隐藏
	FieldName(t reflect.Type, f reflect.StructField) string

	// MethodName 返回给定类型中给定方法的 Javascript 名称
	// 如果这个方法返回空串,给定方法将被隐藏
	MethodName(t reflect.Type, m reflect.Method) string
}

FieldNameMapper 提供 Go 和 Javascript 属性名称之间的自定义映射

func TagFieldNameMapper

func TagFieldNameMapper(tagName string, uncapMethods bool) FieldNameMapper
Example
vm := New()
vm.SetFieldNameMapper(TagFieldNameMapper("json", true))
type S struct {
	Field int `json:"field"`
}
_ = vm.Set("s", S{Field: 42})
res, _ := vm.RunString(`s.field`)
fmt.Println(res.Export())
// 输出: 42
Output:

func UncapFieldNameMapper

func UncapFieldNameMapper() FieldNameMapper
Example
vm := New()
s := testGoReflectMethod_O{
	Test: "passed",
}
vm.SetFieldNameMapper(UncapFieldNameMapper())
_ = vm.Set("s", s)
res, _ := vm.RunString(`s.test + " and " + s.method("passed too")`)
fmt.Println(res.Export())
// 输出: passed and passed too
Output:

type Flag

type Flag int
const (
	FLAG_NOT_SET Flag = iota
	FLAG_FALSE
	FLAG_TRUE
)

func ToFlag

func ToFlag(b bool) Flag

func (Flag) Bool

func (f Flag) Bool() bool

type FunctionCall

type FunctionCall struct {
	This      Value
	Arguments []Value
}

func (FunctionCall) Argument

func (f FunctionCall) Argument(idx int) Value

type InterruptedError

type InterruptedError struct {
	Exception
	// contains filtered or unexported fields
}

func (*InterruptedError) Error

func (e *InterruptedError) Error() string

func (*InterruptedError) String

func (e *InterruptedError) String() string

func (*InterruptedError) Unwrap

func (e *InterruptedError) Unwrap() error

func (*InterruptedError) Value

func (e *InterruptedError) Value() any

type JsonEncodable

type JsonEncodable interface {
	JsonEncodable() any
}

JsonEncodable 允许使用 JSON.stringify() 来定义 json 注意,如果返回的值本身也实现了 JsonEncodable,它将不会有任何的作用

type Language

type Language int
const (
	Javascript Language = iota
	Golang
)

type Now

type Now func() time.Time

type Object

type Object struct {
	// contains filtered or unexported fields
}

func NewSharedDynamicArray

func NewSharedDynamicArray(a DynamicArray) *Object

NewSharedDynamicArray 与 Runtime.NewDynamicArray 类似,但产生的 Object 可以在多个 Runtimes 之间共享 该对象的原型为空。如果你需要对它运行 Array 的方法,请使用 Array.prototype.[...].call(a, ...),提供的 DynamicArray 必须是协程安全的

func NewSharedDynamicObject

func NewSharedDynamicObject(d DynamicObject) *Object

NewSharedDynamicObject 与 Runtime.NewDynamicObject 类似,但是产生的 Object 可以在多个 Runtime 之间共享 该对象的原型为空。提供的 DynamicObject 必须是协程安全的

func (*Object) ClassName

func (o *Object) ClassName() string

func (*Object) DefineAccessorProperty

func (o *Object) DefineAccessorProperty(name string, getter, setter Value, configurable, enumerable Flag) error

func (*Object) DefineAccessorPropertySymbol

func (o *Object) DefineAccessorPropertySymbol(name *Symbol, getter, setter Value, configurable, enumerable Flag) error

func (*Object) DefineDataProperty

func (o *Object) DefineDataProperty(name string, value Value, writable, configurable, enumerable Flag) error

func (*Object) DefineDataPropertySymbol

func (o *Object) DefineDataPropertySymbol(name *Symbol, value Value, writable, configurable, enumerable Flag) error

func (*Object) Delete

func (o *Object) Delete(name string) error
Example
vm := New()
obj := vm.NewObject()
_ = obj.Set("test", true)
before := obj.Get("test")
_ = obj.Delete("test")
after := obj.Get("test")
fmt.Printf("before: %v, after: %v", before, after)
// 输出: before: true, after: <nil>
Output:

func (*Object) DeleteSymbol

func (o *Object) DeleteSymbol(name *Symbol) error

func (*Object) Equals

func (o *Object) Equals(other Value) bool

func (*Object) Export

func (o *Object) Export() (ret any)

Export 将 Object 导出为纯粹的 Go 类型 如果对象是一个包装好的 Go 值(用 ToValue() 创建),则返回原始值 如果对象是一个函数,返回 func(FunctionCall) 值。注意,在函数内部抛出的异常会导致 panic,这也会使 Runtime 处于无法使用的状态。 因此,这些值只能在另一个用 Go 实现的 ES 函数里面使用。对于从 Go 中调用一个函数,请使用 AssertFunction() 或 Runtime.ExportTo() 对于 Map,返回条目列表为 [][2]any 对于 Set,返回元素列表为 []any 对于 Proxy,返回 Proxy 对于 Promise,返回 Promise 对于 DynamicObject 或 DynamicArray,返回基础处理句柄 对于数组,返回 []any 在所有其他情况下,以 map[string]any 的形式返回可枚举的非符号属性 如果在这个过程中抛出了一个 Javascript 异常,这个方法将抛出类型为 *Exception 的panic

Example (Map)
vm := New()
m, err := vm.RunString(`
	new Map([[1, true], [2, false]]);
	`)
if err != nil {
	panic(err)
}
exp := m.Export()
fmt.Printf("%T, %v\n", exp, exp)
// 输出: [][2]interface {}, [[1 true] [2 false]]
Output:

func (*Object) ExportType

func (o *Object) ExportType() reflect.Type

ExportType 返回由 Export() 返回的值的类型

func (*Object) Get

func (o *Object) Get(name string) Value

Get 通过名称获取一个对象的属性 如果在这个过程中抛出了一个 Javascript 异常,这个方法将抛出类型为 *Exception 的panic

func (*Object) GetSymbol

func (o *Object) GetSymbol(sym *Symbol) Value

GetSymbol 返回一个符号属性的值。对于常用的符号(如SymIterator、SymToStringTag等),使用 Sym* 值之一 如果在这个过程中抛出了一个 Javascript 异常,这个方法将抛出类型为 *Exception 的panic

func (*Object) Keys

func (o *Object) Keys() (keys []string)

Keys 返回 Object 的可枚举 Key 的列表 如果在这个过程中抛出了一个 Javascript 异常,这个方法将抛出类型为 *Exception 的panic

func (*Object) MarshalJSON

func (o *Object) MarshalJSON() ([]byte, error)

MarshalJSON 返回对象的 JSON 表示。它等同于 JSON.stringify(o) 这里实现了 json.Marshaler,这样就可以使用 json.Marshal() 而不需要 Export()

func (*Object) Prototype

func (o *Object) Prototype() *Object

Prototype 返回对象的原型,与 Object.getPrototypeOf() 相同。如果原型为空,则返回nil

func (*Object) SameAs

func (o *Object) SameAs(other Value) bool

func (*Object) Set

func (o *Object) Set(name string, value any) error

func (*Object) SetPrototype

func (o *Object) SetPrototype(proto *Object) error

SetPrototype 设置对象的原型,与 Object.setPrototypeOf() 相同。将 proto 设置为 nil 等同于 Object.setPrototypeOf(null)

func (*Object) SetSymbol

func (o *Object) SetSymbol(name *Symbol, value any) error
Example
type IterResult struct {
	Done  bool
	Value Value
}

vm := New()
vm.SetFieldNameMapper(UncapFieldNameMapper())

o := vm.NewObject()
_ = o.SetSymbol(SymIterator, func() *Object {
	count := 0
	iter := vm.NewObject()
	_ = iter.Set("next", func() IterResult {
		if count < 10 {
			count++
			return IterResult{
				Value: vm.ToValue(count),
			}
		}
		return IterResult{
			Done: true,
		}
	})
	return iter
})
_ = vm.Set("o", o)

res, err := vm.RunString(`
	var acc = "";
	for (var v of o) {
		acc += v + " ";
	}
	acc;
	`)
if err != nil {
	panic(err)
}
fmt.Println(res)
// 输出: 1 2 3 4 5 6 7 8 9 10
Output:

func (*Object) StrictEquals

func (o *Object) StrictEquals(other Value) bool

func (*Object) String

func (o *Object) String() string

func (*Object) Symbols

func (o *Object) Symbols() []*Symbol

Symbols 返回 Object 的可枚举符号属性的列表 如果在这个过程中抛出了一个 Javascript 异常,这个方法将抛出类型为 *Exception 的panic

func (*Object) ToBoolean

func (o *Object) ToBoolean() bool

func (*Object) ToFloat

func (o *Object) ToFloat() float64

func (*Object) ToInteger

func (o *Object) ToInteger() int64

func (*Object) ToNumber

func (o *Object) ToNumber() Value

func (*Object) ToObject

func (o *Object) ToObject(*Runtime) *Object

func (*Object) ToString

func (o *Object) ToString() Value

type Program

type Program struct {
	// contains filtered or unexported fields
}

func Compile

func Compile(name, src string, strict bool) (*Program, error)

Compile 将会创建一个 Javascript 代码的内部形式,之后可以使用 Runtime.RunProgram() 方法运行 这个内部形式不会以任何方式链接到运行时,因此可以在多个运行时中运行

func CompileAST

func CompileAST(prg *jast.Program, strict bool) (*Program, error)

CompileAST 与 Compile 一致,但是它接受一个 Javascript AST 形式的代码

func MustCompile

func MustCompile(name, src string, strict bool) *Program

MustCompile 与 Compile 一样,但是如果代码不能被编译,就会出现 panic 它简化了持有已编译的 Javascript 代码的全局变量的安全初始化

type Promise

type Promise struct {
	// contains filtered or unexported fields
}

Promise 是一个围绕 ECMAScript Promise 的 Go 封装器。对它调用 Runtime.ToValue() 会返回基础对象。在一个 Promise 对象上调用 Export() 会返回一个 Promise 使用 Runtime.NewPromise() 来创建。在一个零对象或 nil 上调用 Runtime.ToValue() 会返回空值 Promise 的实例不是协程安全的,参考 Runtime.NewPromise()

func (*Promise) Result

func (p *Promise) Result() Value

func (*Promise) State

func (p *Promise) State() PromiseState

type PromiseRejectionOperation

type PromiseRejectionOperation int
const (
	PromiseRejectionReject PromiseRejectionOperation = iota
	PromiseRejectionHandle
)

type PromiseRejectionTracker

type PromiseRejectionTracker func(p *Promise, operation PromiseRejectionOperation)

type PromiseState

type PromiseState int
const (
	PromiseStatePending PromiseState = iota
	PromiseStateFulfilled
	PromiseStateRejected
)

type PropertyDescriptor

type PropertyDescriptor struct {
	Value                              Value
	Writable, Configurable, Enumerable Flag
	Getter, Setter                     Value
	// contains filtered or unexported fields
}

func (*PropertyDescriptor) Empty

func (p *PropertyDescriptor) Empty() bool

func (*PropertyDescriptor) IsAccessor

func (p *PropertyDescriptor) IsAccessor() bool

func (*PropertyDescriptor) IsData

func (p *PropertyDescriptor) IsData() bool

func (*PropertyDescriptor) IsGeneric

func (p *PropertyDescriptor) IsGeneric() bool

type Proxy

type Proxy struct {
	// contains filtered or unexported fields
}

Proxy 是 ECMAScript Proxy 的 Go 封装器。对其调用 Runtime.ToValue() 会返回底层的 Proxy 在 ECMAScript Proxy 上调用 Export() 会返回一个封装器 使用 Runtime.NewProxy() 可以创建一个封装器

func (Proxy) Handler

func (p Proxy) Handler() *Object

func (Proxy) Revoke

func (p Proxy) Revoke()

func (Proxy) Target

func (p Proxy) Target() *Object

type ProxyTrapConfig

type ProxyTrapConfig struct {
	GetPrototypeOf              func(target *Object) (prototype *Object)                                                // 针对 Object.getPrototypeOf, Reflect.getPrototypeOf, __proto__, Object.prototype.isPrototypeOf, instanceof 的捕获
	SetPrototypeOf              func(target *Object, prototype *Object) (success bool)                                  // 针对 Object.setPrototypeOf, Reflect.setPrototypeOf 的捕获
	IsExtensible                func(target *Object) (success bool)                                                     // 针对 Object.isExtensible, Reflect.isExtensible 的捕获
	PreventExtensions           func(target *Object) (success bool)                                                     // 针对 Object.preventExtensions, Reflect.preventExtensions 的捕获
	GetOwnPropertyDescriptor    func(target *Object, prop string) (propertyDescriptor PropertyDescriptor)               // 针对 Object.getOwnPropertyDescriptor, Reflect.getOwnPropertyDescriptor (字符串属性) 的捕获
	GetOwnPropertyDescriptorIdx func(target *Object, prop int) (propertyDescriptor PropertyDescriptor)                  // 针对 Object.getOwnPropertyDescriptor, Reflect.getOwnPropertyDescriptor (整型属性) 的捕获
	GetOwnPropertyDescriptorSym func(target *Object, prop *Symbol) (propertyDescriptor PropertyDescriptor)              // 针对 Object.getOwnPropertyDescriptor, Reflect.getOwnPropertyDescriptor (符号属性) 的捕获
	DefineProperty              func(target *Object, key string, propertyDescriptor PropertyDescriptor) (success bool)  // 针对 Object.defineProperty, Reflect.defineProperty (字符串属性) 的捕获
	DefinePropertyIdx           func(target *Object, key int, propertyDescriptor PropertyDescriptor) (success bool)     // 针对 Object.defineProperty, Reflect.defineProperty (整型属性) 的捕获
	DefinePropertySym           func(target *Object, key *Symbol, propertyDescriptor PropertyDescriptor) (success bool) // 针对 Object.defineProperty, Reflect.defineProperty (符号属性) 的捕获
	Has                         func(target *Object, property string) (available bool)                                  // 针对 in,with 操作符,Reflect.has (字符串属性) 的捕获
	HasIdx                      func(target *Object, property int) (available bool)                                     // 针对 in,with 操作符,Reflect.has (整型属性) 的捕获
	HasSym                      func(target *Object, property *Symbol) (available bool)                                 // 针对 in,with 操作符,Reflect.has (符号属性) 的捕获
	Get                         func(target *Object, property string, receiver Value) (value Value)                     // 针对读取属性值,Reflect.get (字符串属性) 的捕获
	GetIdx                      func(target *Object, property int, receiver Value) (value Value)                        // 针对读取属性值,Reflect.get (整型属性) 的捕获
	GetSym                      func(target *Object, property *Symbol, receiver Value) (value Value)                    // 针对读取属性值,Reflect.get (符号属性) 的捕获
	Set                         func(target *Object, property string, value Value, receiver Value) (success bool)       // 针对设置属性值,Reflect.set (字符串属性) 的捕获
	SetIdx                      func(target *Object, property int, value Value, receiver Value) (success bool)          // 针对设置属性值,Reflect.set (整型属性) 的捕获
	SetSym                      func(target *Object, property *Symbol, value Value, receiver Value) (success bool)      // 针对设置属性值,Reflect.set (符号属性) 的捕获
	DeleteProperty              func(target *Object, property string) (success bool)                                    // 针对 delete 操作符,Reflect.deleteProperty (字符串属性) 的捕获
	DeletePropertyIdx           func(target *Object, property int) (success bool)                                       // 针对 delete 操作符,Reflect.deleteProperty (整型属性) 的捕获
	DeletePropertySym           func(target *Object, property *Symbol) (success bool)                                   // 针对 delete 操作符,Reflect.deleteProperty (符号属性) 的捕获
	OwnKeys                     func(target *Object) (object *Object)                                                   // 针对 Object.getOwnPropertyNames, Object.getOwnPropertySymbols, Object.keys, Reflect.ownKeys 的捕获
	Apply                       func(target *Object, this Value, argumentsList []Value) (value Value)                   // 针对函数调用,Function.prototype.apply, Function.prototype.call, Reflect.apply 的捕获
	Construct                   func(target *Object, argumentsList []Value, newTarget *Object) (value *Object)          // 针对 new 操作符,Reflect.construct 的捕获
}

ProxyTrapConfig 为实现 Proxy 捕获提供了一个简化友好的 Go API 如果定义了 *Idx 捕获,它就会被调用来处理整数属性键,包括负数。注意,这只包括代表典型整数的字符串属性键(即 "0"、"123",但不包括 "00"、"01"、"1" 或 "-0") 为了提高效率,超过 2^53 的整数的字符串不会被检查是否是典型的,即 *Idx 捕获将收到 "9007199254740993" 和 "9007199254740994" 尽管前者在 ECMAScript 中不是典型的表示(Number("9007199254740993") === 9007199254740992) 参考 https://262.ecma-international.org/#sec-canonicalnumericindexstring 如果没有设置 *Idx 捕获,就会使用相应的字符串捕获

type RandSource

type RandSource func() float64

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

func New

func New() *Runtime

New 创建一个 Javascript 运行时的实例,可以用来运行代码。多个实例可以被创建并同时使用,但是不能在不同的运行时之间传递 JS 值

func (*Runtime) CaptureCallStack

func (r *Runtime) CaptureCallStack(depth int, stack []StackFrame) []StackFrame

CaptureCallStack 将当前的调用堆栈帧附加到堆栈切片(可以是nil),直到指定的深度 如果深度 <= 0 或超过可用的帧数,则返回整个栈 这个方法对于并发使用并不安全,只能由运行中的脚本中的 Go 函数调用

func (*Runtime) ClearInterrupt

func (r *Runtime) ClearInterrupt()

ClearInterrupt 重置中断标志。通常情况下,如果运行时有可能被 Interrupt() 所打断,则需要在运行时可以重新使用之前调用

func (*Runtime) CreateObject

func (r *Runtime) CreateObject(proto *Object) *Object

func (*Runtime) ExportTo

func (r *Runtime) ExportTo(v Value, target any) error

ExportTo 将一个 Javascript 值转换为指定的 Go 值。第二个参数必须是一个非空的指针,如果不能转换,则返回错误

关于具体案例的说明:

# 空接口
   导出为一个空的 any,与 Value.Export() 产生的类型相同的值

# 数值类型
   导出到数字类型使用标准的 ECMAScript 转换操作,与向非钳制类型的数组项赋值时使用相同

# 函数
   导出到一个 func 将创建一个严格类型的'网关'到一个可以从 Go 中调用的 ES 函数内
   使用 Runtime.ToValue() 将参数转换为 ES 值。如果 func 没有返回值,则返回值被忽略。如果 func 正好有一个返回值,
   则使用 ExportTo() 将其转换为适当的类型。如果 func 正好有 2 个返回值,并且第二个值是 error ,那么异常将被捕获并作为*Exception返回
   在所有其他情况下,异常会导致 panic。任何额外的返回值都被清零

   注意,如果你想捕捉并返回异常作为 error,并且你不需要返回值,func(...) error 将不能像预期那样工作。在这种情况下,error 被映射到函数的返回值,而不是异常,这仍然会导致 panic
   使用 func(...) (Value, error) 代替,并且忽略Value

   'this' 的值将永远被设置为 'undefined'

# map 类型
   一个 ES map 可以被导出到 Go map 类型中。如果任何导出的键值是非哈希的,操作就会产生 panic(就像 reflect.Value.SetMapIndex() 那样)
   将一个 ES Set 导出到一个 map 类型,导致 map 被填充了(元素)->(零值)键/值对。如果有任何值是非哈希的,操作就会产生 panic(就像reflect.Value.SetMapIndex()那样)
   Symbol.iterator 被忽略了,任何其他对象都会用自己的可枚举的非符号属性来填充 map

# slice 类型
   将一个 ES Set 导出到一个 slice 类型中,会导致其元素被导出
   将任何实现可迭代协议的对象导出为 slice 类型,都将导致 slice 被迭代的结果所填充
   数组被视为可迭代(即覆盖 Symbol.iterator 会影响结果)
   如果一个对象有 length 属性,并且不是一个函数,那么它就被当作数组一样处理。产生的 slice 将包含 obj[0], ... obj[length-1]
   对于任何其他对象,将返回一个错误

# 数组类型
   只要长度匹配,任何可以导出为 slice 类型的东西也可以导出为数组类型。如果不匹配,就会返回一个错误

# Proxy
   代理对象的处理方式与从 ES 代码中访问它们的属性(如 length 或 Symbol.iterator)相同。这意味着将它们导出到 Slice 类型中可以工作,
   但是将代理的 map 导出到 map 类型中不会同时导出其内容,因为代理不被认可为 map。这也适用于代理的 Set
Example (ArrayLikeToSlice)
vm := New()
v, err := vm.RunString(`
	({
		length: 3,
		0: 1,
		1: 2,
		2: 3
	});
	`)
if err != nil {
	panic(err)
}

var arr []int
err = vm.ExportTo(v, &arr)
if err != nil {
	panic(err)
}

fmt.Println(arr)
// 输出: [1 2 3]
Output:

Example (Func)
const SCRIPT = `
	function f(param) {
		return +param + 2;
	}
	`

vm := New()
_, err := vm.RunString(SCRIPT)
if err != nil {
	panic(err)
}

var fn func(string) string
err = vm.ExportTo(vm.Get("f"), &fn)
if err != nil {
	panic(err)
}

fmt.Println(fn("40")) // 注意,函数中的 _this_ 值是 undefined
// 输出: 42
Output:

Example (FuncThrow)
const SCRIPT = `
	function f(param) {
		throw new Error("testing");
	}
	`

vm := New()
_, err := vm.RunString(SCRIPT)
if err != nil {
	panic(err)
}

var fn func(string) (string, error)
err = vm.ExportTo(vm.Get("f"), &fn)
if err != nil {
	panic(err)
}
_, err = fn("")

fmt.Println(err)
// 输出: Error: testing at f (<eval>:3:9(3))
Output:

Example (FuncVariadic)
const SCRIPT = `
	function f() {
		return Array.prototype.join.call(arguments, ",");
	}
	`
vm := New()
_, err := vm.RunString(SCRIPT)
if err != nil {
	panic(err)
}

var fn func(args ...any) string
err = vm.ExportTo(vm.Get("f"), &fn)
if err != nil {
	panic(err)
}
fmt.Println(fn("a", "b", 42))
// 输出: a,b,42
Output:

Example (IterableToSlice)
vm := New()
v, err := vm.RunString(`
	function reverseIterator() {
	    const arr = this;
	    let idx = arr.length;
	    return {
			next: () => idx > 0 ? {value: arr[--idx]} : {done: true}
	    }
	}
	const arr = [1,2,3];
	arr[Symbol.iterator] = reverseIterator;
	arr;
	`)
if err != nil {
	panic(err)
}

var arr []int
err = vm.ExportTo(v, &arr)
if err != nil {
	panic(err)
}

fmt.Println(arr)
// 输出: [3 2 1]
Output:

Example (MapToMap)
vm := New()
m, err := vm.RunString(`
	new Map([[1, true], [2, false]]);
	`)
if err != nil {
	panic(err)
}
exp := make(map[int]bool)
err = vm.ExportTo(m, &exp)
if err != nil {
	panic(err)
}
fmt.Println(exp)
// 输出: map[1:true 2:false]
Output:

Example (MapToSlice)
vm := New()
m, err := vm.RunString(`
	new Map([[1, true], [2, false]]);
	`)
if err != nil {
	panic(err)
}
exp := make([][]any, 0)
err = vm.ExportTo(m, &exp)
if err != nil {
	panic(err)
}
fmt.Println(exp)
// 输出: [[1 true] [2 false]]
Output:

Example (MapToTypedSlice)
vm := New()
m, err := vm.RunString(`
	new Map([[1, true], [2, false]]);
	`)
if err != nil {
	panic(err)
}
exp := make([][2]any, 0)
err = vm.ExportTo(m, &exp)
if err != nil {
	panic(err)
}
fmt.Println(exp)
// 输出: [[1 true] [2 false]]
Output:

Example (SetToMap)
vm := New()
s, err := vm.RunString(`
	new Set([1, 2, 3])
	`)
if err != nil {
	panic(err)
}
m := make(map[int]struct{})
err = vm.ExportTo(s, &m)
if err != nil {
	panic(err)
}
fmt.Println(m)
// 输出: map[1:{} 2:{} 3:{}]
Output:

Example (SetToSlice)
vm := New()
s, err := vm.RunString(`
	new Set([1, 2, 3])
	`)
if err != nil {
	panic(err)
}
var a []int
err = vm.ExportTo(s, &a)
if err != nil {
	panic(err)
}
fmt.Println(a)
// 输出: [1 2 3]
Output:

func (*Runtime) Get

func (r *Runtime) Get(name string) (ret Value)

Get 在全局环境中获取指定的变量 相当于在非严格模式下通过名称解除引用一个变量。如果变量未被定义,则返回nil 注意,这与 GlobalObject().Get(name) 不同,因为如果存在一个全局词法绑定(let 或 const),就会使用它 如果在这个过程中抛出了一个 Javascript 异常,这个方法将以 *Exception 的形式出现

func (*Runtime) GlobalObject

func (r *Runtime) GlobalObject() *Object

func (*Runtime) Interrupt

func (r *Runtime) Interrupt(v any)

Interrupt 中断一个正在运行的 Javascript。相应的Go调用将返回一个包含 v 的 *InterruptedError 如果中断后的堆栈是空的,那么当前排队的 Promise 解析/拒绝作业将被清除而不被执行 注意,它只在 Javascript 代码中工作,它不会中断原生 Go 函数(包括所有的内置函数) 如果执行中断时,当前没有脚本正在运行,那么在下一次 Run*() 调用时就会立即中断,为了避免这种情况,请使用ClearInterrupt()

func (*Runtime) New

func (r *Runtime) New(construct Value, args ...Value) (o *Object, err error)

New 等同于 new 运算符,允许从 Go 中直接调用它

func (*Runtime) NewArray

func (r *Runtime) NewArray(items ...any) *Object
Example
vm := New()
array := vm.NewArray(1, 2, true)
_ = vm.Set("array", array)
res, err := vm.RunString(`
	var acc = "";
	for (var v of array) {
		acc += v + " ";
	}
	acc;
	`)
if err != nil {
	panic(err)
}
fmt.Println(res)
// 输出: 1 2 true
Output:

func (*Runtime) NewArrayBuffer

func (r *Runtime) NewArrayBuffer(data []byte) ArrayBuffer

func (*Runtime) NewDynamicArray

func (r *Runtime) NewDynamicArray(a DynamicArray) *Object

NewDynamicArray 创建一个由 DynamicArray 处理程序支持的数组对象 它与 NewDynamicObject 相似,区别在于: 1.该对象是一个数组(即 Array.isArray() 将返回 true,并且它将有长度属性) 2.对象的原型将被初始设置为 Array.prototype 3.除了长度,该对象不能有任何自己的字符串属性

func (*Runtime) NewDynamicObject

func (r *Runtime) NewDynamicObject(d DynamicObject) *Object

NewDynamicObject 创建一个由 DynamicObject 处理程序支持的对象 这个对象的特性如下: 1.它的所有属性都是可写、可列举和可配置的数据属性。任何试图定义一个不符合这一点的属性的行为都会失败 2.它总是可扩展的,不能使其成为不可扩展的。尝试执行 Object.preventExtensions() 将会失败 3.它的原型最初被设置为 Object.prototype,但可以使用常规机制(Go 中的 Object.SetPrototype() 或 JS 中的 Object.setPrototypeOf() )来改变 4.它不能有自己的符号属性,但是它的原型可以。例如,如果你需要一个迭代器支持,你可以创建一个普通的对象,在该对象上设置 Symbol.iterator,然后把它作为一个原型 Export() 返回原始的 DynamicObject

这种机制类似于 ECMAScript Proxy,但是因为所有的属性都是可枚举的,而且对象总是可扩展的,所以不需要进行不变性检查,这就不需要有一个目标对象了,而且效率更高

func (*Runtime) NewGoError

func (r *Runtime) NewGoError(err error) *Object

func (*Runtime) NewObject

func (r *Runtime) NewObject() (v *Object)

func (*Runtime) NewPromise

func (r *Runtime) NewPromise() (promise *Promise, resolve func(result any), reject func(reason any))

NewPromise 创建并返回一个 Promise 和对其进行解析的函数 警告:返回的值不是协程安全的,不能在 vm 运行时并行调用 为了使用这个方法,你需要一个事件循环,例如 nodejs 包内的

loop := NewEventLoop()
loop.Start()
defer loop.Stop()
loop.RunOnLoop(func(vm *Runtime) {
	p, resolve, _ := vm.NewPromise()
	vm.Set("p", p)
    go func() {
  		time.Sleep(500 * time.Millisecond)   // 或执行任何其他阻塞性操作
		loop.RunOnLoop(func(*Runtime) { // resolve() 必须在循环中调用,不能在这里调用
			resolve(result)
		})
	}()
 }

func (*Runtime) NewProxy

func (r *Runtime) NewProxy(target *Object, nativeHandler *ProxyTrapConfig) Proxy

func (*Runtime) NewTypeError

func (r *Runtime) NewTypeError(args ...any) *Object

func (*Runtime) RunProgram

func (r *Runtime) RunProgram(p *Program) (result Value, err error)

RunProgram 在全局上下文中执行预先编译的代码

func (*Runtime) RunScript

func (r *Runtime) RunScript(name, src string) (Value, error)

RunScript 在全局环境中执行给定的字符串

func (*Runtime) RunString

func (r *Runtime) RunString(str string) (Value, error)

RunString 在全局环境中执行给定的字符串

func (*Runtime) Set

func (r *Runtime) Set(name string, value any) error

Set 在全局环境中设置指定的变量 相当于在非严格模式下运行 "name = value",需要首先使用 ToValue() 转换数值

Example (Lexical)
r := New()
_, err := r.RunString("let x")
if err != nil {
	panic(err)
}
err = r.Set("x", 1)
if err != nil {
	panic(err)
}
fmt.Print(r.Get("x"), r.GlobalObject().Get("x"))
// 输出: 1 <nil>
Output:

func (*Runtime) SetFieldNameMapper

func (r *Runtime) SetFieldNameMapper(mapper FieldNameMapper)

SetFieldNameMapper 为 Go 类型设置一个自定义字段名称映射器 将其设为 nil 可以恢复默认行为

func (*Runtime) SetMaxCallStackSize

func (r *Runtime) SetMaxCallStackSize(size int)

SetMaxCallStackSize 设置最大的函数调用深度。当超过时,一个 *StackOverflowError 被抛出并由 RunProgram 或 Callable 调用返回 这对于防止无限递归引起的内存耗尽很有用。默认值是 math.MaxInt32 这个方法(和其他的 Set* 方法一样)对于并发使用是不安全的,只能从 vm 所在的协程或者当 vm 没有运行时调用

func (*Runtime) SetParserOptions

func (r *Runtime) SetParserOptions(opts ...parser.Option)

SetParserOptions 设置解析器选项,以便在代码中被 RunString、RunScript 和 eval() 使用

Example
vm := New()
vm.SetParserOptions(parser.WithDisableSourceMaps)

res, err := vm.RunString(`
	"I did not hang!";
//# sourceMappingURL=/dev/zero`)

if err != nil {
	panic(err)
}
fmt.Println(res.String())
// 输出: I did not hang!
Output:

func (*Runtime) SetPromiseRejectionTracker

func (r *Runtime) SetPromiseRejectionTracker(tracker PromiseRejectionTracker)

SetPromiseRejectionTracker 注册了一个函数,该函数将在两种情况下被调用: 1.当一个 Promise 在没有任何处理程序的情况下被拒绝时(操作参数设置为 PromiseRejectionReject) 2.当一个处理程序第一次被添加到被拒绝的 Promise 时(操作参数设置为 PromiseRejectionHandle) 设置一个跟踪器会替换任何现有的跟踪器。将其设置为 nil 则禁用该功能 参考 https://tc39.es/ecma262/#sec-host-promise-rejection-tracker

func (*Runtime) SetRandSource

func (r *Runtime) SetRandSource(source RandSource)

SetRandSource 为这个 Runtime 设置随机源。如果不调用,则使用默认的 math/rand

func (*Runtime) SetTimeSource

func (r *Runtime) SetTimeSource(now Now)

SetTimeSource 为这个Runtime设置当前的时间源,如果不调用,则使用默认的time.Now()

func (*Runtime) ToValue

func (r *Runtime) ToValue(i any) Value

ToValue 将 Go 值转换为最合适类型的 Javascript值。结构类型(如 struct、map 和 slice)被包装起来,这样所产生的变化就会反映在原始值上,可以用 Value.Export() 来检索

警告! 这些包装好的 Go 值与原生 ECMAScript 值的行为方式不同。如果你打算在ECMAScript中修改它们,请记住以下注意事项:

  1. 如果一个普通的 Javascript 对象被分配为包装的 Go struct、map 或数组中的一个元素,它将被 Export(),因此会被复制,这可能会导致JavaScript中出现意外的行为: m := map[string]any{} vm.Set("m", m) vm.RunString(` var obj = {test: false}; m.obj = obj; // obj 被 Export(),即复制到一个新的 map[string]any 并且这个 map 被设置到 m["obj"] obj.test = true; // 注意,这里的 m.obj.test 依然是 false `) fmt.Println(m["obj"].(map[string]any)["test"]) // 打印出 false
  1. 如果你在 ECMAScript 中修改嵌套的非指针式复合类型(struct、slice 和数组),要小心,尽可能避免在 ECMAScript 中修改它们,ECMAScript 和 Go 的一个根本区别在于 前者的所有对象都是引用,而在 Go 中你可以有一个字面的 struct 或数组。请看下面的例子:

    type S struct { Field int }

    a := []S{{1}, {2}} // 节片的字面结构 vm.Set("a", &a) vm.RunString(` let tmp = {Field: 1}; a[0] = tmp; a[1] = tmp; tmp.Field = 2; `)

    在ECMAScript中,我们希望a[0].Field和a[1].Field等于2,但是这是不可能的(或者至少在没有复杂的引用跟踪的情况下是不可行的)。 为了涵盖最常见的使用情况并避免过多的内存分配,"变化时复制" 的机制已被实现(对数组和struct):

    * 当一个嵌套的复合值被访问时,返回的 ES 值成为对字面值的引用。这保证了像 'a[0].Field = 1' 这样的事情能如期进行,对 'a[0].Field' 的简单访问不会导致导致对 a[0] 的复制 * 原始的容器(在上述例子中是 'a' )会跟踪返回的引用值,如果 a[0] 被重新赋值(例如,通过直接赋值、删除或缩小数组),旧的 a[0] 被复制,先前的返回值成为该副本的一个引用

    例如:

    let tmp = a[0]; // 没有复制,tmp 是对 a[0] 的引用 tmp.Field = 1; // 此时 a[0].Field === 1 a[0] = {Field: 2}; // tmp现在是对旧值副本的引用(Field ===1) a[0].Field === 2 && tmp.Field === 1; // true

    * 由原地排序(使用 Array.prototype.sort() )引起的数组值交换不被视为重新分配,而是引用被调整为指向新的索引 * 对内部复合值的赋值总是进行复制(有时还进行类型转换)

    a[1] = tmp; // a[1] 现在是 tmp 的复制 tmp.Field = 3; // 不影响 a[1].Field

3. 非可寻址 struct、slice 和数组被复制。这有时可能会导致混乱,因为分配给内部字段的赋值似乎并不奏效

	a1 := []any{S{1}, S{2}}
	vm.Set("a1", &a1)
	vm.RunString(`
	   a1[0].Field === 1; // true
	   a1[0].Field = 2;
	   a1[0].Field === 2; // false, 因为它真正做的是复制 a1[0],将其字段设置为2,并立即将其删除
	`)

   另一种方法是让 a1[0].Field 成为一个不可写的属性,如果需要修改的话,就需要手动复制值,但是这可能是不切实际的
   注意,这同样适用于 slice。如果一个 slice 是通过值传递的(而不是作为一个指针),调整 slice 的大小并不反映在原来的值。此外,扩展 slice 可能会导致底层数组被重新分配和复制
   例如:

	a := []any{1}
	vm.Set("a", a)
	vm.RunString(`a.push(2); a[0] = 0;`)
	fmt.Println(a[0]) // 打印 "1"

   关于个别类型的说明:
   #原始类型
      原始类型(数字、字符串、布尔)被转换为相应的 Javascript 原语
   # 字符串
      由于 ECMAScript(使用 UTF-16)和 Go(使用 UTF-8)从 JS 到 Go 的转换可能是有损失的。字符串值必须是一个有效的UTF-8。如果不是,无效的字符会被替换为utf8.RuneError
      但是后续的 Export() 的行为没有被指定(它可能返回原始值,或一个被替换的无效字符)
   # Nil
      Nil 被转换为 null
   # 函数
      func(FunctionCall) Value被视为一个本地 Javascript 函数。这将提高性能,因为没有自动转换参数和返回值的类型(这涉及到反射)。试图将该函数用作构造函数将导致 TypeError

      func(ConstructorCall) *Object 被视为一个本地构造函数,允许用 new 操作符一起使用

		func MyObject(call ConstructorCall) *Object {
			call.This.Set("method", method)
	        //...
	        // instance := &myCustomStruct{}
	        // instanceValue := vm.ToValue(instance).(*Object)
	        // instanceValue.SetPrototype(call.This.Prototype())
	        // return instanceValue
	        return nil
	     }
	     runtime.Set("MyObject", MyObject)

      那么它可以在 JS 中使用,如下:

        var o = new MyObject(arg);
	    var o1 = MyObject(arg); // 等价于上面的
	    o instanceof MyObject && o1 instanceof MyObject; // true

      当一个本地构造函数被直接调用时(没有new操作符),其行为取决于这个值:如果它是一个对象,它会被传递,否则会创建一个新的对象,就像它是用 new 操作符调用的。在这两种情况下,call.NewTarget 将是 nil

	  func(ConstructorCall, *Runtime) *Object 的处理方法同上,只是 *Runtime 也被作为参数传递
      任何其他的 Go 函数都会被包装起来,这样参数就会自动转换为所需的 Go 类型,而返回值被转换为 Javascript 值(使用此方法)。 如果无法转换,则会抛出 TypeError

      有多个返回值的函数返回一个数组。如果最后一个返回值是一个 error,它不会被返回,而是被转换成一个 JS 异常。如果错误是 *Exception,它将被原样抛出,否则它将被包裹在一个 GoError 中
      注意,如果正好有两个返回值,并且最后一个是 error,函数会原样返回第一个值,而不是一个数组

   # Structs
      struct 被转换为类似对象的值。字段和方法可以作为属性使用,它们的值是这个方法(ToValue())的结果应用于相应的 Go 值
      字段属性是可写的、不可配置的,方法属性是不可写和不可配置的
      试图定义一个新的属性或删除一个现有的属性将会失败(在严格模式下抛出),除非它是一个 Symbol 属性。符号属性只存在于包装器中,不影响底层的 Go 值
      请注意,由于每次访问一个属性都会创建一个包装器,因此可能会导致一些意想不到的结果,例如:

		type Field struct{
		}
		type S struct {
			Field *Field
		}
		var s = S{
			Field: &Field{},
	 	}
	 	vm := New()
	 	vm.Set("s", &s)
	 	res, err := vm.RunString(`
	 		var sym = Symbol(66);
	 		var field1 = s.Field;
	 		field1[sym] = true;
	 		var field2 = s.Field;
	 		field1 === field2; // true, 因为 == 操作比较的是被包装的值,而不是包装器
	 		field1[sym] === true; // true
	 		field2[sym] === undefined; // true
	 	`)

      这同样适用于来自 map 和 slice 的值

   # 对 time.Time 的处理
      time.Time 没有得到特殊的处理,因此它的转换就像其他的结构一样,提供对其所有方法的访问
      这样做是故意的,而不是将其转换为 Date,因为这两种类型并不完全兼容,time.Time 包含时区,而 JS 的 Date 不包含,因此隐含地进行转换会导致信息的丢失
      如果你需要将其转换为 Date,可以在 JS 中完成。

		var d = new Date(goval.UnixNano()/1e6);

      或者在 Go 中完成:

	 	now := time.Now()
	 	vm := New()
	 	val, err := vm.New(vm.Get("Date").ToObject(vm), vm.ToValue(now.UnixNano()/1e6))
	 	if err != nil {
			...
	 	}
	 	vm.Set("d", val)

      请注意,Value.Export() 对于一个 Date 值会返回包含当地时区的 time.Time

   # Maps
      带有字符串或整数键类型的 map 被转换为 host 对象,其行为大体上与 Javascript 对象类似

   # 带有方法的 Maps
      如果一个 map 类型定义了方法,那么产生的 Object 的属性代表了它的方法,而不是通过 map 的 key
      这是因为在 Javascript中,object.key 和 object[key] 之间是没有区别的,这一点与 Go 不同
      如果需要访问 map 的值,可以通过定义另一个方法来实现,也可以通过定义一个外部 getter 函数

   # Slices
      slice 被转换为 host 对象,其行为在很大程度上类似于 Javascript 的数组。它有适当的原型,所有常用的方法都可以使用
      然而,有一点需要注意:转换后的数组不能包含空洞(因为 Go slice 不能)。这意味着 hasOwnProperty(n) 总是在 n < length 时返回 true
      删除一个 索引小于 length 的项将被设置为零值(但属性会保留)。nil slice 元素将被转换为 null
      访问一个超过 length 的元素会返回 undefined。也请看上面的警告,关于将 slice 作为值(相较于指针)

   # 数组
      数组的转换与 slice 的转换类似,只是产生的数组不能调整大小(length 属性是不可写的)
      任何其他类型被转换为基于反射的通用 host 对象。根据底层类型的不同,它的行为类似于与数字、字符串、布尔值或对象
      请注意,底层类型不会丢失,调用 Export() 返回原始的 Go 值。这适用于所有基于反射的类型

type Script

type Script struct {
	// contains filtered or unexported fields
}

Script Golang 脚本定义

func NewGo

func NewGo(script string) *Script

NewGo 建立一个 Go 的运行时框架,必须紧跟着 defer Close(),以保证执行完毕后内存会释放

func (*Script) Close

func (s *Script) Close() error

Close 终止脚本并释放所占用的资源

func (*Script) Execute

func (s *Script) Execute(args ...any) (any, error)

Execute 按照送入的参数来执行脚本,得到执行后的返回值

type StackFrame

type StackFrame struct {
	// contains filtered or unexported fields
}

func (*StackFrame) FuncName

func (f *StackFrame) FuncName() string

func (*StackFrame) Position

func (f *StackFrame) Position() file.Position

func (*StackFrame) SrcName

func (f *StackFrame) SrcName() string

func (*StackFrame) Write

func (f *StackFrame) Write(b *bytes.Buffer)

func (*StackFrame) WriteToValueBuilder

func (f *StackFrame) WriteToValueBuilder(b *valueStringBuilder)

type StackOverflowError

type StackOverflowError struct {
	Exception
}

type Symbol

type Symbol struct {
	// contains filtered or unexported fields
}

Symbol 符号,是一个包含 ECMAScript Symbol 基元的 Value。符号只能用NewSymbol()来创建。不允许使用零值和复制值(即*s1 = *s2) 常见的符号都可以使用 Sym* 包变量(如SymIterator)来访问 符号可以被多个运行时共享

func NewSymbol

func NewSymbol(s string) *Symbol
Example
sym1 := NewSymbol("66")
sym2 := NewSymbol("66")
fmt.Printf("%s %s %v", sym1, sym2, sym1.Equals(sym2))
// 输出: 66 66 false
Output:

func (*Symbol) Equals

func (s *Symbol) Equals(o Value) bool

func (*Symbol) Export

func (s *Symbol) Export() any

func (*Symbol) ExportType

func (s *Symbol) ExportType() reflect.Type

func (*Symbol) SameAs

func (s *Symbol) SameAs(other Value) bool

func (*Symbol) StrictEquals

func (s *Symbol) StrictEquals(o Value) bool

func (*Symbol) String

func (s *Symbol) String() string

func (*Symbol) ToBoolean

func (s *Symbol) ToBoolean() bool

func (*Symbol) ToFloat

func (s *Symbol) ToFloat() float64

func (*Symbol) ToInteger

func (s *Symbol) ToInteger() int64

func (*Symbol) ToNumber

func (s *Symbol) ToNumber() Value

func (*Symbol) ToObject

func (s *Symbol) ToObject(r *Runtime) *Object

func (*Symbol) ToString

func (s *Symbol) ToString() Value

type Value

type Value interface {
	ToInteger() int64

	ToString() Value
	String() string
	ToFloat() float64
	ToNumber() Value
	ToBoolean() bool
	ToObject(*Runtime) *Object
	SameAs(Value) bool
	Equals(Value) bool
	StrictEquals(Value) bool
	Export() any
	ExportType() reflect.Type
	// contains filtered or unexported methods
}

Value 表示 ECMAScript 的值 Export 返回一个纯粹的 Go 值,其类型取决于 Value 的类型 对于整数,它是 int64 对于任何其他数字(包括无穷大、NaN 和负零),它是 float64 对于字符串,它是一个字符串。请注意,unicode 字符串被转换为 UTF-8,无效的编码位置用 utf8.RuneError 代替 对于布尔值,它是布尔值 对于 null 和 undefined,它是nil 对于 Object,它取决于 Object 的类型,更多的细节在 Object.Export()

func False

func False() Value

func NaN

func NaN() Value

NaN 返回 JS NaN 值

func NegativeInf

func NegativeInf() Value

NegativeInf 返回 JS 负无穷大值

func Null

func Null() Value

Null 返回 JS null 值

func PositiveInf

func PositiveInf() Value

PositiveInf 返回 JS 正无穷大值

func True

func True() Value

func Undefined

func Undefined() Value

Undefined 返回 JS 的未定义值。注意,如果全局的 "未定义" 属性被改变,它仍然返回原来的值

Directories

Path Synopsis
Package file 供 AST 使用的文件操作抽象
Package file 供 AST 使用的文件操作抽象
Package unistring 是一个混合ASCII/UTF16字符串的实现 对于 ASCII 字符串,底层处理相当于普通的 Go 字符串 对于 unicode 字符串,底层处理为 []uint16 ,符合 UTF16 的编码规则,第0个元素为0xFEFF
Package unistring 是一个混合ASCII/UTF16字符串的实现 对于 ASCII 字符串,底层处理相当于普通的 Go 字符串 对于 unicode 字符串,底层处理为 []uint16 ,符合 UTF16 的编码规则,第0个元素为0xFEFF

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL