为什么 ownKeys Proxy 陷阱与 Object.keys() 不起作用?

7
MDN上的Proxy ownKeys陷阱文档中,它指出它将拦截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))

3个回答

5
简单来说,Object.keys只返回带有可枚举标志的属性。为了检查它,它会调用内部方法[[GetOwnProperty]]来获取每个属性的描述符。但是,在这里,由于没有属性,其描述符为空,没有可枚举标志,因此它被跳过。
为了使Object.keys返回一个属性,我们需要它存在于对象中,并带有可枚举标志,或者我们可以拦截对[[GetOwnProperty]]的调用(陷阱getOwnPropertyDescriptor可以实现),并返回具有enumerable: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']

源代码


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))


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

虽然可能是正确的,但仅有代码的答案只对提问者有帮助,对他们或未来的访问者没有任何好处。请考虑改进您的回答。 - Rohit Gupta
我的朋友,我测试了代码,它运行得很好。我应该怎么做来改进答案? - paliz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接