Search code examples
javascriptpropertydescriptor

Is there a JavaScript equivalent for Swift's @dynamicMemberLookup?


In Swift I can define a type which returns the name of a requested property as string using @dynamicMemberLookup:

@dynamicMemberLookup struct S {
  subscript(dynamicMember member: String) -> String { member }
}

let s = S()
s.foo  // returns "foo"
s.bar  // returns "bar"

Is there a way to achieve this behavior in JavaScript? In some sense, I'm looking for a way to override Object.getOwnPropertyDescriptor. I thought something like the following would've worked, but it's not.

const cachedGOPD = Object.getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor = function (o, p) {
  if (o instanceof S) return { get() { return p } }
  return cachedGOPD(o, p)
}

I don't know if Object.getOwnPropertyDescriptor is called when requesting an object property.


Solution

  • This is technically achievable with a Proxy, no need to modify getOwnPropertyDescriptor:

    const makeS = () => new Proxy({}, {
      get(_, prop) {
        console.log('getter called on', prop);
        return prop;
      }
    });
    
    const s = makeS()
    console.log(s.foo)  // returns "foo"
    console.log(s.bar)  // returns "bar"

    It's an interesting theoretical exercise, but in practice, proxies are slow, and this is a bit weird. In most cases, well-designed code shouldn't need to rely on such a thing.