From eb1f15ee67d22593a0760c3df624da2ea4e41cb6 Mon Sep 17 00:00:00 2001 From: Dmitry Panov Date: Thu, 27 Jun 2024 20:50:25 +0100 Subject: [PATCH] Added Object.GetOwnPropertyNames(). Closes #584. --- object_test.go | 8 ++++++++ runtime.go | 4 ++-- value.go | 20 +++++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/object_test.go b/object_test.go index f2b54ce9..45b95bc5 100644 --- a/object_test.go +++ b/object_test.go @@ -495,6 +495,14 @@ func ExampleObject_Delete() { // Output: before: true, after: } +func ExampleObject_GetOwnPropertyNames() { + vm := New() + obj := vm.NewObject() + obj.DefineDataProperty("test", vm.ToValue(true), FLAG_TRUE, FLAG_TRUE, FLAG_FALSE) // define a non-enumerable property that Keys() would not return + fmt.Print(obj.GetOwnPropertyNames()) + // Output: [test] +} + func TestObjectEquality(t *testing.T) { type CustomInt int type S struct { diff --git a/runtime.go b/runtime.go index c240ddea..9f4e999f 100644 --- a/runtime.go +++ b/runtime.go @@ -2366,7 +2366,7 @@ func (r *Runtime) Set(name string, value interface{}) error { // Equivalent to dereferencing a variable by name in non-strict mode. If variable is not defined returns nil. // Note, this is not the same as GlobalObject().Get(name), // because if a global lexical binding (let or const) exists, it is used instead. -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (r *Runtime) Get(name string) Value { n := unistring.NewFromString(name) if v, exists := r.global.stash.getByName(n); exists { @@ -3141,7 +3141,7 @@ func assertCallable(v Value) (func(FunctionCall) Value, bool) { } // InstanceOf is an equivalent of "left instanceof right". -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (r *Runtime) InstanceOf(left Value, right *Object) (res bool) { return instanceOfOperator(left, right) } diff --git a/value.go b/value.go index aeb96762..e5031e72 100644 --- a/value.go +++ b/value.go @@ -772,7 +772,7 @@ func (o *Object) baseObject(*Runtime) *Object { // // In all other cases returns own enumerable non-symbol properties as map[string]interface{}. // -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (o *Object) Export() interface{} { return o.self.export(&objectExportCtx{}) } @@ -787,20 +787,20 @@ func (o *Object) hash(*maphash.Hash) uint64 { } // Get an object's property by name. -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (o *Object) Get(name string) Value { return o.self.getStr(unistring.NewFromString(name), nil) } // GetSymbol returns the value of a symbol property. Use one of the Sym* values for well-known // symbols (such as SymIterator, SymToStringTag, etc...). -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (o *Object) GetSymbol(sym *Symbol) Value { return o.self.getSym(sym, nil) } // Keys returns a list of Object's enumerable keys. -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (o *Object) Keys() (keys []string) { iter := &enumerableIter{ o: o, @@ -813,8 +813,18 @@ func (o *Object) Keys() (keys []string) { return } +// GetOwnPropertyNames returns a list of all own string properties of the Object, similar to Object.getOwnPropertyNames() +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. +func (o *Object) GetOwnPropertyNames() (keys []string) { + for item, next := o.self.iterateStringKeys()(); next != nil; item, next = next() { + keys = append(keys, item.name.String()) + } + + return +} + // Symbols returns a list of Object's enumerable symbol properties. -// This method will panic with an *Exception if a JavaScript exception is thrown in the process. +// This method will panic with an *Exception if a JavaScript exception is thrown in the process. Use Runtime.Try to catch these. func (o *Object) Symbols() []*Symbol { symbols := o.self.symbols(false, nil) ret := make([]*Symbol, len(symbols))