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

时间:2018-06-19 11:12:17

标签: javascript proxy-pattern

In an example from Node.js Design patterns

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

What is the need for the method delegation i.e. to redefine the Proxy.prototype.goodbye method again when the method from original Object will be automatically be called as the prototype chain has been set i.e. Proxy.prototype = Object.create(proto). Thanks in advance.

2 个答案:

答案 0 :(得分:2)

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

应简化为

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

也许他们希望使用原型继承来实现 all (非覆盖)方法的隐式委派,如下所示:

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;
}

答案 1 :(得分:1)

新实例化的Proxy不能从subject继承-直接在subject上的属性仅在代理的 subject 属性上可用。仅subject prototype 方法在代理对象本身上立即可用。因此,在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