Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I extend the Array class in Babel?

I'd like to define a shortcut method for inspecting the end of a stack.

The following works in Firefox:

const Stack = class extends Array {
  last() {
    return this[this.length - 1];
  }
}

However, after compiling this with Babel, it doesn't work:

var Stack = function (_Array) {
  _inherits(Stack, _Array);

  function Stack() {
    _classCallCheck(this, Stack);

    return _possibleConstructorReturn(this, Object.getPrototypeOf(Stack).apply(this, arguments));
  }

  _createClass(Stack, [{
    key: 'last',
    value: function last() {
      return this[this.length - 1];
    }
  }]);

  return Stack;
}(Array);


console.log(Stack.prototype.last); // works
console.log((new Stack()).last); // doesn't work
Array.prototype.last = Stack.prototype.last;
console.log((new Stack()).last); // works

For some reason, I can add functions to the new prototype, but they won't be available to instances of that prototype unless they're inserted directly into the Array prototype (which is obviously bad practice due to potential side effects).


Update: There might be several ways to get around this (including Proxy objects, or extending the prototype manually instead of using extends), but since my Stack doesn't really need most of the Array methods, I'm now simply using a wrapper.

  const Stack = class {
    constructor(...x) {
      this.arr = [...x];
    }
    pop() {
      return this.arr.pop();
    }
    push(...x) {
      return this.arr.push(...x);
    }
    top() {
      return this.arr[this.arr.length - 1];
    }
    size() {
      return this.arr.length;
    }
  }
like image 956
Christoph Burschka Avatar asked Oct 30 '16 01:10

Christoph Burschka


2 Answers

I'm not sure about Babel support but node.js started supporting (partially) Array subclassing since version 4.3.2 and implemented full subclassing support in version 6.8.1 (http://node.green/#Array-is-subclassable). So if you're using node 6 Array subclassing should work.

If Babel is failing you you can always do it the "classical" way:

// Code tested and works in 6.3.1:
function Stack = () {};
Stack.prototype = Object.create(Array.prototype);
Stack.prototype.last = function () {
    return this[this.length - 1];
}

var s = new Stack();
like image 81
slebetman Avatar answered Nov 16 '22 06:11

slebetman


You might use this plug-in (Babel 6): https://www.npmjs.com/package/babel-plugin-transform-builtin-extend

The plugin describes some limitations for IE <= 10, however.

Update: But this plugin is not even needed for Babel 7.

like image 2
Brett Zamir Avatar answered Nov 16 '22 06:11

Brett Zamir