Can `new` be optional?

Logan Smyth loganfsmyth at gmail.com
Sun Nov 5 22:09:51 UTC 2017


> I also don't see how decorators can solve it.

Making to wrapper for class constructor to allow the constructor to
callable would be fairly straightforward, e.g.

```
function callable(cls) {
  function Wrapper(...args) {
    return Reflect.construct(cls, args, new.target || cls);
  }
  Object.defineProperty(Wrapper, "name", { value: cls.name });
  Object.setPrototypeOf(Wrapper, cls);
  Wrapper.prototype = cls.prototype;
  return Wrapper;
}

const Example = callable(class Example {});

Example();
```
and thus potentially
```
@callable
class Example {}
```

I know you said "At the cost of non-zero overhead." but it seems like this
would be something engines could optimize more easily than proxies.

> This seems like a really short sighted issue.  Why can't calling a class
just invoke it's constructor?

I think the big question for me when discussing this with people is, is it
more surprising to throw a clear error in these case, or to do something
close but not quite the same as if it were an ES5-style constructor?

```
class Foo {
  constructor() {
    this.foo = 4;
  }
}

var obj = {};
var inst = Foo.call(obj);

// what happens?
// obj.foo => 4 or undefined
// inst => obj, new object, or undefined
// inst.foo => 4 or undefined
```
To be consistent with ES6 class semantics it has to be that a new instance
is returned and `obj` is 100% ignored but that are very much not what you'd
get if you replaced the class there with `function Foo(){ this.foo = 4; }`.
Isn't that its own set of confusing changes?

Specifically for "This seems like a really short sighted issue" I'd say
this is the opposite of short-sighted. There's nothing preventing support
for this in the future, but if it got added with a behavior that ended up
confusing people _more_ than not having it at all, then we'd be stuck with
it for good.


On Sun, Nov 5, 2017 at 11:53 AM, J Decker <d3ck0r at gmail.com> wrote:

>
>
> On Sun, Nov 5, 2017 at 7:53 AM, Andrea Giammarchi <
> andrea.giammarchi at gmail.com> wrote:
>
>> oldie but goldie ?
>>
>> ```js
>> Object.defineProperty(
>>   Function.prototype,
>>   'new',
>>   {
>>     configurable: true,
>>     value(...args) {
>>       return new this(...args);
>>     }
>>   }
>> );
>> ```
>>
>> doesn't make new optional, just moves it, and doesn't apply to 'class'es
> which the OP is saying.
>
>
>>
>>
>>
>>
>> On Sun, Nov 5, 2017 at 11:28 AM, Oriol _ <oriol-bugzilla at hotmail.com>
>> wrote:
>>
>>> > Why can't `new` be optional?
>>>
>>> When you call a function, you are using the internal [[Call]] method.
>>> When you use the `new` operator, it's the internal [[Construct]] method.
>>>
>>> They are different things, so IMO avoiding `new` when you are
>>> instantiating is bad practice.
>>>
>>>
> Of course it is... with out new, classes throw an exception.
>
> This seems like a really short sighted issue.  Why can't calling a class
> just invoke it's constructor?
>
> I also don't see how decorators can solve it.
>
> Seems just as arbitrary as the underscore proposal not accepting
> underscore trailing a number or before or after a decimal.
>
> Maybe, it would be better to ask 'Why does calling a class throw an
> exception instead of just creating a new instance.
>
>
>> But if you really want to avoid `new` when using ES6 `class` syntax, you
>>> can use proxies, e.g.
>>>
>>> ```js
>>> let MyClass = new Proxy(class MyClass {
>>>   constructor(arg) { this.arg = arg; }
>>> }, {
>>>   apply: (target, thisArg, args) => Reflect.construct(target, args)
>>> });
>>> MyClass(1); // { arg: 1 }
>>> new MyClass(2); // { arg: 2 }
>>> ```
>>>
>>
> At the cost of non-zero overhead.
>
>
>> --Oriol
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20171105/fc55db03/attachment.html>


More information about the es-discuss mailing list