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