2

Per my answer to this question, chrome allows you to do the following (chrome 49):

class Person {
  constructor() {
    this.fn = function(a) { this.a = a; };
    return new Proxy(this, {
      apply: function(target, thisArg, args) {
        return target.fn.apply(target, args);
      }
    });
  }
}
var person = new Person();
person(3);
person.a; //3
typeof person; //object

Whereas FF makes you do this:

class Person extends Function {
  constructor() {
    super();
    this.fn = function(a) { this.a = a; };
    return new Proxy(this, {
      apply: function(target, thisArg, args) {
        return target.fn.apply(target, args);
      }
    });
  }
}
var person = new Person();
person(3);
person.a; //3
typeof person; //function

So requiring a call to super in a subclass constructor that references this is apparently correct according to MDN, but in terms of allowing a proxy to make a non-function callable, which browser has the correct behavior here? Chrome which lets you, or FF which requires extending Function?

UPDATE

Per Bergi's comment below, relevant spec section is 9.5.14, specifically step 7.

FINAL UPDATE

This is a bug in certain versions of Chrome (I'm too lazy to test exactly which) Chrome 51 at least has the correct behavior of throwing an error.

Community
  • 1
  • 1
Jared Smith
  • 19,721
  • 5
  • 45
  • 83
  • @dandavis Because it enables a sort of operator overloading, you can specify how the function application operator `()` acts on a class, without necessarily having the instances of that class be functions. Not sure that doing so is all that great an idea, but it *is* an interesting one (at least to me). Indeed, javascript is definitely moving in that direction with the addition of well-known symbols. That returned proxy isn't limited to just the apply trap either. – Jared Smith Mar 18 '16 at 17:34
  • @dandavis Oh yeah, there's no question that this is a 'bend the language in a potentially interesting way' question vs. a 'get important stuff done yesterday' question. Its anything but readable. – Jared Smith Mar 18 '16 at 17:45
  • possible duplicate of [ES6 proxies can't be functions?](http://stackoverflow.com/q/26291836/1048572)? Also have a look at [this](http://stackoverflow.com/a/29798915/1048572) for some spec references – Bergi Mar 18 '16 at 18:36
  • "*in terms of allowing a proxy to make a non-function callable*" - that's clearly a violation of the spec – Bergi Mar 18 '16 at 18:36
  • @Bergi so bug in chrome then? Sounds from your answer to the other question like objects without a `[[Call]]` slot shouldn't respond to `()` even if they've been proxied with an actual function call on the apply trap. – Jared Smith Mar 18 '16 at 19:06
  • Yes, exactly. Btw, it you want to subclass functions I'd recommend `function F(callable) { return Object.setPrototypeOf(callable, new.target.prototype); } F.prototype = Function.prototype;` and then `class Person extends F { constructor() { super(function call(){…}} …}` – Bergi Mar 18 '16 at 22:07
  • Possible duplicate of [Can't set “apply” trap to Proxy object](http://stackoverflow.com/q/32360218/1529630) – Oriol Mar 20 '16 at 02:56

0 Answers0