Ways to extend Array object in javascript

ES6

class SubArray extends Array {
    last() {
        return this[this.length - 1];
    }
}
var sub = new SubArray(1, 2, 3);
sub // [1, 2, 3]
sub instanceof SubArray; // true
sub instanceof Array; // true

Using __proto__

(old answer, not recommended, may cause performance issues)

function SubArray() {
  var arr = [ ];
  arr.push.apply(arr, arguments);
  arr.__proto__ = SubArray.prototype;
  return arr;
}
SubArray.prototype = new Array;

Now you can add your methods to SubArray

SubArray.prototype.last = function() {
  return this[this.length - 1];
};

Initialize like normal Arrays

var sub = new SubArray(1, 2, 3);

Behaves like normal Arrays

sub instanceof SubArray; // true
sub instanceof Array; // true

A while ago I read the book Javascript Ninja written by John Resig, the creator of jQuery. He proposed a way to mimic array-like methods with a plain JS object. Basically, only length is required.

var obj = {
    length: 0, //only length is required to mimic an Array
    add: function(elem){
        Array.prototype.push.call(this, elem);
    },
    filter: function(callback) {
        return Array.prototype.filter.call(this, callback); //or provide your own implemetation
    }
};

obj.add('a');
obj.add('b');
console.log(obj.length); //2
console.log(obj[0], obj[1]); //'a', 'b'

I don't mean it's good or bad. It's an original way of doing Array operations. The benefit is that you do not extend the Array prototype. Keep in mind that obj is a plain object, it's not an Array. Therefore obj instanceof Array will return false. Think obj as a façade.

If that code is of interest to you, read the excerpt Listing 4.10 Simulating array-like methods.


Method names should be lowercase. Prototype should not be modified in the constructor.

function Array3() { };
Array3.prototype = new Array;
Array3.prototype.add = Array3.prototype.push

in CoffeeScript

class Array3 extends Array
   add: (item)->
     @push(item) 

If you don't like that syntax, and you HAVE to extend it from within the constructor, Your only option is:

// define this once somewhere
// you can also change this to accept multiple arguments 
function extend(x, y){
    for(var key in y) {
        if (y.hasOwnProperty(key)) {
            x[key] = y[key];
        }
    }
    return x;
}


function Array3() { 
   extend(this, Array.prototype);
   extend(this, {
      Add: function(item) {
        return this.push(item)
      }

   });
};

You could also do this

ArrayExtenstions = {
   Add: function() {

   }
}
extend(ArrayExtenstions, Array.prototype);



function Array3() { }
Array3.prototype = ArrayExtenstions;

In olden days, 'prototype.js' used to have a Class.create method. You could wrap all this is a method like that

var Array3 = Class.create(Array, {
    construct: function() {

    },    
    Add: function() {

    }
});

For more info on this and how to implement, look in the prototype.js source code