Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Array subclass ES5
// No need to sub class Array if what you need is just an extended
// array. Example below illustrates the way to extend Array.
function SubArray() {
return Object.defineProperties(Array.prototype.slice.call(arguments), SubArrayDescriptor)
}
SubArray.prototype = Array.prototype
var SubArrayDescriptor =
{ constructor: { value: SubArray }
, last: { value: function last() {
return this[this.length - 1]
}}
}
// Sub classing array works as expected. Many people have false expectation that
// special behavior of number properties (sub[10]) is supposed to be inherited by a subclass.
function SubArray() {
var subArray = Object.create(SubArray.prototype)
Array.prototype.push.apply(subArray, arguments)
return subArray
}
SubArray.prototype = Object.create(Array.prototype,
{ constructor: { value: SubArray }
, last: { value: function last() {
return this[this.length - 1]
}}
})

I know that lot of time has passed since you make this gist, but this works nowadays... (chrome/firefox)

function SubArray() {
  this.push.apply(this, arguments);
}
SubArray.prototype = Object.create(Array.prototype, {
  constructor : { 
     value : SubArray
  },
  lastElement : {
    value : function() {
      return this[this.length - 1];
    }
  }
})

var sub = new SubArray(1, 2, 3);
sub instanceof SubArray; //true
sub instanceof Array; //true
sub.lastElement() //3

cpcallen commented Jun 29, 2017

@royiojas:

It "works" because Array.push "is intentionally generic", and updates .length for you. But your new SubArray is not an array:

> Array.isArray(sub);
false
> sub[3] = 4;
4
> sub.length
3

Wouldn't a factory function be more elegant?

/**
 * Specialised array for objects with a size property
 * @param {number} length The length of the new Array
 */
function SizeArray (length) {
  return Object.create(new Array(length), {
    /**
     * Returns the sum of each object size property
     */
    size: {
      get () {
        return this.reduce((n, a) => n += a.size, 0)
      }
    }
  })
}
const buffer = new SizeArray(2000)

Hmm.. maybe not

buffer instanceof Array // -> true
Array.isArray(buffer) // -> false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment