0

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.

arvin
  • 43
  • 6

2 Answers2

2

This code does not make any sense. There's no reason to involve inheritance here - as you noticed it makes everything confusing.

It should be simplified to

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

Or if one wanted to use a prototype object to share the methods, then

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

Maybe they wanted to anticipate using prototype inheritance to achieve implicit delegation of all (non-overwritten) methods, which would look like this:

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;
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

The newly instantiated Proxy does not inherit from the subject - the properties directly on subject's are only available on the proxy's subject property. Only the prototype methods of the subject are available immediately on the Proxy object itself. So, in the case that goodbye is a property directly on the instantiated object, you wouldn't be able to access it directly were the Proxy.prototype.goodbye = ... line not there:

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

Those methods are available through the instantiated proxy's .subject, but not through the proxy itself, unless you explicitly assign to Proxy.prototype.goodbye as in the original code.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • But *why* does it inherit from the subject's prototype? That makes no sense, given that the proxy doesn't have any instance properties. – Bergi Jun 19 '18 at 11:41