是否有 JavaScript 等同于 Swift 的 @dynamicMemberLookup?

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

在 Swift 中,我可以使用 @dynamicMemberLookup:

定义一个类型,其中 returns 所请求 属性 的名称作为字符串
@dynamicMemberLookup struct S {
  subscript(dynamicMember member: String) -> String { member }
}

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

有没有办法在 JavaScript 中实现这种行为?从某种意义上说,我正在寻找一种方法来覆盖 Object.getOwnPropertyDescriptor。我以为像下面这样的东西会奏效,但事实并非如此。

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

不知道在请求对象属性时是否调用了Object.getOwnPropertyDescriptor

这在技术上可以通过代理实现,无需修改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"

这是一个有趣的理论练习,但在实践中,代理很慢,这有点奇怪。在大多数情况下,设计良好的代码应该不需要依赖这样的东西。