Christoph Burschka Christoph Burschka - 29 days ago 15
Javascript Question

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;
}
}

Answer

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();
Comments