ES6
In ES6 you can extend Array using the class syntax
class SubArray extends Array {
constructor() {
super(...arguments);
}
first() {
return this[0];
}
}
length will work as expected
var sa = new SubArray('foo', 'bar');
sa[2] = 'baz';
sa.length; // 3
sa.first(); // "foo"
sa instanceof SubArray; // true
Pre-ES5
Up to and including ES5 there is no way to cleanly extend Array in the usual constructor-prototype way without losing functionality, instead you have to add properties to an Array instance
function SubArray() {
var arr = Array.apply(null, arguments);
arr.first = function () {return this[0];};
return arr;
}
Using this no longer requires new as an Object is returned from the function, and instanceof will not be able to determine SubArray.
var sa = SubArray('foo', 'bar');
sa[2] = 'baz';
sa.length; // 3
sa.first(); // "foo"
sa instanceof SubArray; // false -- this gets broken
ES5 (slow)
In an ES5 environment where behaviour is more important than speed, you can force the prototype chain as desired using Object.setPrototypeOf (see MDN warning), this is "a bit of a hack" and would look like
function SubArray() {
var arr = Array.apply(null, arguments);
Object.setPrototypeOf(arr, SubArray.prototype);
return arr;
}
SubArray.prototype = Object.create(Array.prototype);
SubArray.prototype.first = function () {return this[0];};
Again, new is no-longer required but this time the behaviour of instances is exactly as would be expected if it was extended normally.
var sa = SubArray('foo', 'bar');
sa[2] = 'baz';
sa.length; // 3
sa.first(); // "foo"
sa instanceof SubArray; // true
.lengthwon't work as expected,.applywon't work as expected, you have to create a normal Array instance and add properties to it as desired.lengthproperty) that has issues when trying to subclass in ES5 or earlier.