在 JavaScript 中实现代理的方法委托给父级

Method delegation to the parent in case of implementing proxies in JavaScript

示例来自 Node.js 设计模式

  function createProxy(subject) {
     var proto = Object.getPrototypeOf(subject);
     function Proxy(subject) {
       this.subject = subject;
     }
     Proxy.prototype = Object.create(proto);
     //proxied method
     Proxy.prototype.hello = function() {
       return this.subject.hello() + ' world!';
     }
     //delegated method
     Proxy.prototype.goodbye = function() {
       return this.subject.goodbye
         .apply(this.subject, arguments);
}
     return new Proxy(subject);
   }

当原型链已经自动调用原始Object的方法时,方法委托需要什么,即重新定义Proxy.prototype.goodbye方法已设置,即 Proxy.prototype = Object.create(proto)。提前致谢。

新实例化的 Proxy 不继承自 subject - subject 上的直接属性仅在代理的 subject[=32 上可用=] 属性。只有 subjectprototype 方法在 Proxy 对象本身上立即可用。因此,如果 goodbye 是直接在实例化对象上的 属性,如果 Proxy.prototype.goodbye = ... 行不存在,您将无法直接访问它:

function createProxy(subject) {
  var proto = Object.getPrototypeOf(subject);
  function Proxy(subject) {
    this.subject = subject;
  }
  Proxy.prototype = Object.create(proto);
  //proxied method
  Proxy.prototype.hello = function() {
    return this.subject.hello() + ' world!';
  }
  return new Proxy(subject);
}
const prox = createProxy({
  goodbye() {
    console.log('goodbye.')
  }
});
prox.goodbye();

这些方法可通过实例化代理的 .subject 使用,但不能通过代理本身使用,除非您像在原始代理中那样显式分配给 Proxy.prototype.goodbye代码。

这段代码没有任何意义。没有理由在这里涉及继承 - 正如您所注意到的那样,它会使一切变得混乱。

应该简化为

function createProxy(subject) {
  return {
    // proxied method
    hello() {
      return subject.hello() + ' world!';
    },
    // delegated method
    goodbye() {
      return subject.goodbye.apply(subject, arguments);
    }
  };
}

或者如果想使用原型对象来共享方法,那么

function Proxy(subject) {
  this.subject = subject;
}
// proxied method
Proxy.prototype.hello = function() {
  return this.subject.hello() + ' world!';
};
// delegated method
Proxy.prototype.goodbye = function() {
  return this.subject.goodbye.apply(this.subject, arguments);
};

function createProxy(subject) {
  return new Proxy(subject);
}

也许他们想预期使用原型继承来实现 所有(非覆盖)方法的隐式委托,这看起来像这样:

function createProxy(subject) {
  var proxy = Object.create(subject);
  // proxied method
  proxy.hello = function() {
    return subject.hello() + ' world!';
  }
  // 'goodbye' and everything else on the subject is delegated
  return proxy;
}