Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: can't extend the native Map/WeakMap/Set/WeakSet class #2107

Open
stuartZhang opened this issue Apr 22, 2016 · 7 comments
Open

Bug: can't extend the native Map/WeakMap/Set/WeakSet class #2107

stuartZhang opened this issue Apr 22, 2016 · 7 comments

Comments

@stuartZhang
Copy link

Bug: can't extend the native Map/WeakMap/Set/WeakSet class.
Description: Only the ES 6 classes can't be extended. However, both the traditional built-in classes (e.g. Date) and the custom classes are able to be successfully extended to instantiate a sub class.

Source code:

class B extends Map{
  get b(){
    return 20;
  }
}
const b = new B();
console.log(b.b);

Run the JavaScript file by:

$ ../node_modules/.bin/traceur test.js

Runtime Error:

ModuleEvaluationError: Constructor Set requires 'new'
    at B.Set (native)
    at tailCall (/home/stzhang/var/webapps/connect/main/node_modules/traceur/bin/traceur.js:932:24)
    at Function.apply (/home/stzhang/var/webapps/connect/main/node_modules/traceur/bin/traceur.js:963:20)
    at new B (/home/stzhang/var/webapps/connect/main/unit_tests/mojioApiTokenRetrieval.bbjs:494:43)
    at /home/stzhang/var/webapps/connect/main/unit_tests/mojioApiTokenRetrieval.bbjs:500:11
@stuartZhang
Copy link
Author

stuartZhang commented Apr 23, 2016

I suspect that the below statement throws an error that the "new" operator is required.

$traceurRuntime.superConstructor(B).apply(this, arguments);

In the ES6 program, the above corresponds to the statement "super();".

@stuartZhang
Copy link
Author

Referencing the feedback from the previus issue: #1413, it works as design.

@arv arv reopened this Apr 23, 2016
@arv
Copy link
Collaborator

arv commented Apr 23, 2016

There is a work around:

Compile:

class M extends Map {
  constructor() {
    super();
  }
}

to:

class M extends Map {
  constructor() {
    const self = new Map();
    self.__proto__ = M.prototype;  // should really be new.targe.prototype
    return self;
  }
}

but there are 2 issues making this hard:

  1. Detecting when to do this transformation.
  2. It needs new.target to work correctly and new.target is too expensive to emulate

@zloirock
Copy link

  1. Simple list of built-in constructors by the spec. Isn't perfect, but better solutions will be much harder.
  2. new.target.prototype -> Object.getPrototypeOf(this)

@arv
Copy link
Collaborator

arv commented Apr 23, 2016

You cannot touch this before calling super() in a constructor... but the compiled code is not using a constructor so it seems like it would work.

Another problem would be sub classing M... The way we compile constructors doesn't do the right thing when an object is returned.

@zloirock
Copy link

but the compiled code is not using a constructor so it seems like it would work.

Sure, it's approach for a compiled code, I use it for a long time.

Another problem would be sub classing M

Here required complete subclassing reform like in babel@6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants