3

Very glad to learn of this way of basically subclassing a JavaScript Array (code copied from link):

function SomeType() {
    this.push(16);
}

SomeType.prototype = [];
SomeType.prototype.constructor = SomeType; // Make sure there are no unexpected results

console.log(new SomeType()); // Displays in console as [16]

But this isn't quite complete. Is there a way to fake subclass the Array like this and get the [] method?

var a = [];
a[3]  = true;
console.log(a.length); //=> 4

var s = new SomeType();
s[3]  = true;
console.log(s.length); //=> 1

This way you can still treat it as an array when doing a for loop:

for (var i = 0; i < s.length; i++) {
  var item = s[i];
}
Community
  • 1
  • 1
Lance
  • 75,200
  • 93
  • 289
  • 503
  • 3
    That is a problem... I don't think there's a cross-browser way to solve it. Two things come to mind: 1. Properties - not really cross-browser 2. Just enforce `.push` instead, which works - if at all possible. – Ry- May 26 '12 at 03:16
  • This seems related: http://stackoverflow.com/questions/255041/in-javascript-can-i-override-the-brackets-to-access-characters-in-a-string – xanadont May 26 '12 at 03:28
  • Why would you need to subclass an array anyway? you can create an array and still attach new properties to it. – Joseph May 26 '12 at 04:42

2 Answers2

2

Only works with browsers with __proto__ (which is deprecated ), so it's not cross-browser :

var CustomArray = function ( ) {
  var array = [ 16 ];
  array.__proto__ = this.__proto__;
  return array;
};

CustomArray.prototype = [];
CustomArray.prototype.constructor = CustomArray;

var array = new CustomArray( );
console.log( array instanceof Array );       // true
console.log( array instanceof CustomArray ); // true

array[ 3 ] = 42;
console.log( array.length );                 // 4

I don't think there is any other way to do it.

Maël Nison
  • 7,055
  • 7
  • 46
  • 77
0

I find that the best way to subclass an "Array" is to not subclass an "Array" but rather another "Array-Like-Object", there are plenty of them out there, the one is use is Collection. Basically it does everything Arrays do (including bracket notation) but is a "custom" prototype so it can be easily subclassed unlike native prototypes, which often have issues when they are subclassed.

http://codepen.io/dustinpoissant/pen/AXbjxm?editors=0011

var MySubArray = function(){
  Collection.apply(this, arguments);
  this.myCustomMethod = function(){
    console.log("The second item is "+this[1]);
  };
};
MySubArray.prototype = Object.create(Collection.prototype);

var msa = new MySubArray("Hello", "World");
msa[2] = "Third Item";
console.log(msa);
msa.myCustomMethod();
Dustin Poissant
  • 3,201
  • 1
  • 20
  • 32