Last Updated: May 17, 2017
·
4.921K
· sslotsky

Subclassing JavaScript's Array class

I kept reading over and over again that you just can't subclass Array in JavaScript. Well where I come from (America that is), can't is a four letter word. Fortunately for us, everybody was just plain wrong, and to prove it, I'll demonstrate in JavaScript and Coffeescript.

var Wrapper = function() {
  var name = arguments[0];
  var args = Array.prototype.slice.call(arguments, 1); 
  this.push.apply(this, args);
  return this;
}

Wrapper.prototype = Object.create(Array.prototype);

With a design like this you can pass an arbitrary number of arguments into your wrapper, do what you want with the first n, and use the rest in your collection. Methods like .pop() and properties like length will work out of the box.

Of course Coffeescript gives us the opportunity to pretend that prototypal inheritance doesn't exist, if you're into that sort of thing:

class ArrayWrapper extends Array
  constructor: (title, args...) ->
    @title = title
    @push.apply(@, args)

Enjoy!

3 Responses
Add your response

hi...
first, why do you skip the first argument and assign it to an unused variable name ???
second, the resulting pseudo-array does not behave like an array, try this:

var Wrapper = function() {
var args = Array.prototype.slice.call(arguments, 0);
this.push.apply(this, args);
return this;
}
Wrapper.prototype = Object.create(Array.prototype);
Wrapper.prototype.first = function(){ return this[0] };
var a = new Wrapper('cool',1,2,3);
a.length = 6; //OK
;a.map(function(x) {return x*2}); //OK
a.push('last one'); //OK
;a.first(); //OK
a.length = 3;
a[6]; //it is still there!!!! WRONG, should be undefined
so you see, you still haven't subclassed a Javascript Array ;-)

over 1 year ago ·

Hello, your post helped me, but I want to suggest improvement:


class ArrayWrapper extends Array

  method: -> console.log 'hello'

new ArrayWrapper().method() # This doesn't work!

It is can't be called "class" without methods, so:


class ArrayWrapper

proto = ArrayWrapper.prototype = Object.create Array.prototype

proto.method = -> console.log 'hello' # Yes, we are loosing simple methods notations

new ArrayWrapper().method() # great!

Markdown in this site infuriates me

over 1 year ago ·

Note this class ArrayWrapper extends Array is fully supported in the most recent versions of Chrome, Edge, and Firefox. Although, something akin to what you have provided is definitely needed for older browsers. A middle ground would be to use Proxies, which seem to pre-date Array inheritance support in Edge and Firefox. See https://medium.com/@anywhichway/array-sub-classing-with-support-461ff7c3b819.

over 1 year ago ·