【问题标题】:Why isn't ownKeys Proxy trap working with Object.keys()?为什么 ownKeys 代理陷阱不能与 Object.keys() 一起使用?
【发布时间】:2021-03-28 02:25:31
【问题描述】:

documentation of the Proxy ownKeys trap on MDN 中声明它将拦截Object.keys() 调用:

这个陷阱可以拦截这些操作:

Object.getOwnPropertyNames()

Object.getOwnPropertySymbols()

Object.keys()

Reflect.ownKeys()

但是,从我的测试来看,它似乎不适用于Object.keys

const proxy = new Proxy({}, {
  ownKeys() {
    console.log("called")
    return ["a", "b", "c"]
  }
})

console.log(Object.keys(proxy))

console.log(Object.getOwnPropertyNames(proxy))

console.log(Reflect.ownKeys(proxy))

是 MDN 错了,还是我做错了什么?

【问题讨论】:

    标签: javascript ecmascript-6 es6-proxy


    【解决方案1】:

    原因很简单:Object.keys 只返回带有可枚举标志的属性。为了检查它,它为每个属性调用内部方法[[GetOwnProperty]] 以获取其描述符。而这里,由于没有属性,它的描述符是空的,没有可枚举的标志,所以它被跳过了。

    为了让Object.keys 返回一个属性,我们需要它存在于对象中,带有可枚举标志,或者我们可以拦截对 [[GetOwnProperty]] 的调用(陷阱 getOwnPropertyDescriptor 执行此操作),并返回一个描述符可枚举:true。

    这是一个例子:

    let user = { };
    
    user = new Proxy(user, {
      ownKeys(target) { // called once to get a list of properties
        return ['a', 'b', 'c'];
      },
    
      getOwnPropertyDescriptor(target, prop) { // called for every property
        return {
          enumerable: true,
          configurable: true
          /* ...other flags, probable "value:..." */
        };
      }
    
    });
    
    console.log( Object.keys(user) ); // ['a', 'b', 'c']

    Source

    【讨论】:

      【解决方案2】:

      Object.keys 仅返回对象的 可枚举 自身属性。您的代理没有这样的,或者至少它没有在其getOwnPropertyDescriptor 陷阱中报告它们。它适用于

      const proxy = new Proxy({}, {
        ownKeys() {
          console.log("called ownKeys")
          return ["a", "b", "c"]
        },
        getOwnPropertyDescriptor(target, prop) {
          console.log(`called getOwnPropertyDescriptor(${prop})`);
          return { configurable: true, enumerable: true };
        } 
      })
      
      console.log(Object.keys(proxy))
      
      console.log(Object.getOwnPropertyNames(proxy))
      
      console.log(Reflect.ownKeys(proxy))

      【讨论】:

        猜你喜欢
        • 2017-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多