3

I'm running into problems when trying to inherit from the new Set available in ecmascript 6. The class is defined as such:

function SelectionManager () {
  Set.call(this);
}

SelectionManager.prototype = Object.create(Set.prototype);

SelectionManager.prototype.add = function (unit) {
  unit.setIsSelected(true);
  Set.prototype.add.call(this, unit);
};

/* Some functions left out */

When trying to call add I get the following error: TypeError: Set operation called on non-Set object

The code is available at http://jsfiddle.net/6nq1gqx7/

The draft for ES6 clearly states that it should be possible to subclass Set, what is the correct way of doing so?

Linus Unnebäck
  • 23,234
  • 15
  • 74
  • 89
  • `Uncaught ReferenceError: Set is not defined`. Chrome (37) doesn't seem to be too happy about ES6 – Cerbrus Oct 08 '14 at 11:29
  • Hmm, seems like it's available in Chrome 38. And in Chrome 31 with the flag `Enable Experimental JavaScript` enabled... Chrome 38 was promoted to stable yesterday, it should auto update itself for you in the near future. – Linus Unnebäck Oct 08 '14 at 11:36
  • Ah, yea, it seems the browser's just waiting for a restart, the update's downloaded already :P – Cerbrus Oct 08 '14 at 11:38
  • Reading ["How ECMAScript 5 still does not allow to subclass array"](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/) gave a workaround but the problem they describe shouldn't really apply to `Set`, especially since the spec says it should be subclassable. The workaround is to change the constructor to `var set = new Set();`, `set.__proto__ = SelectionManager.prototype;`, `return set;`, it seems quite dirty though... – Linus Unnebäck Oct 08 '14 at 11:50

3 Answers3

1

Looks like this is being tracked:

https://github.com/google/traceur-compiler/issues/1413

Brian Genisio
  • 47,787
  • 16
  • 124
  • 167
1

No correct way for now. Chrome/V8 (as most other browsers) does not yet properly support subclassing of builtins -- in part because it potentially is quite complicated to implement, and in part because the precise semantics are still wildly in flux, and have just been overthrown at the latest ES6 meeting, with no final resolution yet (as of October 2014).

Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
0

In Chrome, Firefox, and Edge (But not IE11) you can Subclass ES6 Set and Map with this workaround, done with ES6 classes:

class MySet extends Set {
  constructor() {
    // instead of super(), you must write:
    const self = new Set();
    self.__proto__ = MySet.prototype;
    return self;
  }

  // example method:
  add(item) {
    console.log('added!')
    super.add(item); // Or: Set.prototype.add.call(this, item);
  }
}

var mm = new MySet();
console.log(mm.size); // logs 0
mm.add(5);            // logs 'added!'
console.log(mm.size); // logs 1
Simon Sarris
  • 62,212
  • 13
  • 141
  • 171