diff --git a/otto.go b/otto.go index 6135330..99df01b 100644 --- a/otto.go +++ b/otto.go @@ -655,6 +655,25 @@ func (self Object) Keys() []string { return keys } +// Get the keys (and those of the parents) for the object, in order of +// "closest" to "furthest" +func (self Object) KeysByParent() [][]string { + var a [][]string + + for o := self.object; o != nil; o = o.prototype { + var l []string + + o.enumerate(false, func(name string) bool { + l = append(l, name) + return true + }) + + a = append(a, l) + } + + return a +} + // Class will return the class string of the object. // // The return value will (generally) be one of: diff --git a/otto_test.go b/otto_test.go index ca0bd76..33106bd 100644 --- a/otto_test.go +++ b/otto_test.go @@ -851,6 +851,22 @@ func TestAPI(t *testing.T) { }) } +func TestObjectKeys(t *testing.T) { + tt(t, func() { + vm := New() + vm.Eval(`var x = Object.create(null); x.a = 1`) + vm.Eval(`var y = Object.create(x); y.b = 2`) + + o1, _ := vm.Object("x") + is(o1.Keys(), []string{"a"}) + is(o1.KeysByParent(), [][]string{{"a"}}) + + o2, _ := vm.Object("y") + is(o2.Keys(), []string{"b"}) + is(o2.KeysByParent(), [][]string{{"b"}, {"a"}}) + }) +} + func TestUnicode(t *testing.T) { tt(t, func() { test, _ := test()