【问题标题】:How to create a trap for properties on a constructible JavaScript object如何为可构造的 JavaScript 对象上的属性创建陷阱
【发布时间】:2020-12-06 08:56:40
【问题描述】:

Proxy 有一个trap for new operator,理论上它应该允许我们创建将构造函数参数传递给目标对象的代理。它的工作原理示例如下所示:

function monster1(disposition) {
  this.disposition = disposition;
}

const handler1 = {
  construct(target, args) {
    console.log('monster1 constructor called');
    // expected output: "monster1 constructor called"

    return new target(...args);
  },
  
  get(...args) {
    console.info('get trap triggered!')
  }
};

const proxy1 = new Proxy(monster1, handler1);

const instance = new proxy1('fierce')

console.log(instance.disposition);
// expected output: "fierce"

console.log(instance.unknownProp);
// expected output: "get trap triggered!" <-- doesn't happen

这非常有效。除了instance.unknownProp 现在不再触发get 陷阱。我现在如何拦截属性?

【问题讨论】:

  • 陷阱是针对proxy1本身的属性访问,例如proxy1.unknownProp。要捕获实例上的属性访问,您需要在 new 处理程序中创建一个新代理。

标签: javascript javascript-proxy


【解决方案1】:

在Construct 中你有return new target(...args);。这将创建一个新的 JS 对象,没有设置任何代理。

你应该在新创建的对象上设置一个额外的代理来拦截那里的属性访问。

像这样:

function monster1(disposition) {
  this.disposition = disposition;
}

const handler1 = {
  construct(target, args) {
    console.log('monster1 constructor called');
    // expected output: "monster1 constructor called"

    const obj = new target(...args);

    // Return a Proxy instead of object. 
    // We may use the same handler1 here, or we can
    // create another handler with `get`. Both work,.
    return new Proxy(obj, handler1);
  },
  
  get(...args) {
    console.log('get trap triggered!')
    return Reflect.get(...args);
  }
};

const proxy1 = new Proxy(monster1, handler1);

const instance = new proxy1('fierce')

console.log(instance.disposition);
// expected output: "get trap triggered!"
// expected output: "fierce"

console.log(instance.unknownProp);
// expected output: "get trap triggered!"

【讨论】:

  • 天哪,这越来越复杂了
  • Reflect.get(...args) 在里面做什么?或者它怎么知道该怎么做?
  • @jayarjo, Reflect.get(...args) 返回对象属性。它接受对象作为第一个参数和属性名称作为第二个参数。代理的 get 陷阱签名是 get: function(target, prop, receiver),因此允许在代码 sn-p 中使用短语法。
【解决方案2】:

我没试过,但我认为super 是你的答案。 https://www.w3schools.com/jsref/jsref_class_super.asp

【讨论】:

  • 在这种情况下如何使用超级?你知道这样的答案可能会被否决:)
猜你喜欢
  • 2023-03-07
  • 2018-11-23
  • 2015-03-24
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多