Support generation of ES6 classes

Description

Support generation of ES6 classes

ES6 introduced a class syntax to Javascript. Before recent versions a lot of the work done around this were using polyfills, but with the advance of browsers more and more libraries are starting to use this feature natively, and that brings a problem. With the "hacked" ways to get classes you could always call the original constructor from a subclass, this is not true with native ES6 classes. To demonstrate the problem let's take a look at a simple class extension case in JS:

1 2 3 4 5 6 7 8 9 10 11 class A { constructor(x) { this.x = x; } } class B extends A { constructor(foo) { super(foo); } }

An attempt to replicate this without using classes can go as:

1 2 3 4 5 function B(foo) { A.prototype.constructor.call(this, foo); } Reflect.setPrototypeOf(B.prototype, A.prototype)

But trying to call this new constructor with `new B("bar")` triggers a browser exception: `Uncaught TypeError: Class constructor A cannot be invoked without 'new'`.

The root problem is that constructors can't be called as functions, this limits the reach of ClojureScript because it prevents the ability to extend these classes directly, and instead have to fall back to regular JS to handle these cases.

So this makes seems like we need some way to generate actual ES6 classes from Clojurescript (maybe a `defclass` macro?).

Some resources used in this exploration:

https://rete.js.org - library that makes use of native classes and depend on it for its usage
https://esdiscuss.org/topic/extending-an-es6-class-using-es5-syntax - some discussions around simulating es6 classes with es5
https://medium.com/@robertgrosse/how-es6-classes-really-work-and-how-to-build-your-own-fd6085eb326a - more docs around how classes works

But all the resources seems to deal with a time when native classes were not a thing, so they didn't have to deal with native constructor calls.

Environment

All

Status

Assignee

Unassigned

Reporter

Wilker Lucio

Labels

None

Approval

None

Patch

None

Priority

Major
Configure