Array.prototype.fastStackTo combat GC and its impact on animation I created Array.fastStack that adds to the array prototype. It's a sort of stack that bubbles unused objects up and active object down. The objects are never dereferenced and thus do not have a GC impact.I created it some years back and use it all the time and is in every project I have been involved in over that time.But it gathers dust as my usage pattern does not change that much. A second or third pair of eyes would do it some good, so feel free to tear it to bits.As it sits in my libThe Array.prototype object and associated functions and properties.if (Array.prototype.fastStack === undefined) {     Object.defineProperty(Array.prototype, 'fMaxLength', {  // the max number of objects        writable : true,        enumerable : false,        configurable : false,        value : undefined     });     Object.defineProperty(Array.prototype, 'fLength', { // the number of alive objects        writable : true,        enumerable : false,        configurable : false,        value : 0     });     Object.defineProperty(Array.prototype, 'flag', {  // name of alive dead property        writable : true,        enumerable : false,        configurable : false,        value : undefined     });    Object.defineProperty(Array.prototype, 'fNextFree', { // returns if any available the next free object, else undefined        writable : false,        enumerable : false,        configurable : false,        value : function (item) {            if(this.fLength < this.fMaxLength){                this.fLength += 1;                return this[this.fLength-1];            }            return undefined;        }    });    Object.defineProperty(Array.prototype, 'fEach', { // Main iterator bubbles dead object up         writable : false,                             // and alive objects down        enumerable : false,                           // Maintains fLength to the smallest possible value        configurable : false,        value : function (func) {            var i, tail,count,o,len;            len = this.fLength;            i = 0;            tail = 0;            count = 0;            while( i < len ) {                if( this[i][this.flag] !== undefined) {                    count += 1;                    func(this[i], i);                    if(this[i][this.flag] === undefined) {                        tail += 1;                    }else{ // swap unused                        if(tail > 0){                            o = this[i - tail];                            this[i - tail] = this[i];                            this[i] = o;                        }                    }                }                i++;            }            this.fLength = count-tail;        }    });    Object.defineProperty(Array.prototype, 'fEachQ', {  // a slightly faster dumber iterator.        writable : false,        enumerable : false,        configurable : false,        value : function (func) {            var i,len;            len = this.fLength;            i = 0;            while( i < len ) {                if( this[i][this.flag] !== undefined) {                    func(this[i], i);                }                i++;            }        }    });    Object.defineProperty(Array.prototype, 'fastStack', {  // creates a stack of object appending if already assigned.        writable : false,        enumerable : false,        configurable : false,        value : function (size,obj,flag) {   // size is the number of object to add. Obj a description of the object                                             // and flag the name of the dead flag property.            var i, o, j, keys;            if(this.fMaxLength === undefined){                this.fMaxLength = this.length;            }            if(obj[flag] === undefined){                throw new ReferanceError(FastArray object descriptor missing matching flag property '+flag+');            }            this.flag = flag;            keys = Object.keys(obj);            if(this.fMaxLength < size){                for(i = this.fMaxLength; i < size; i++){                    o = {};                    for(j of keys){                        o[j] = undefined;                    }                    this.push(o);                }            }                        this.fLength = 0;            return this.fMaxLength = this.fMaxLength < size ? size : this.fMaxLength;        }    });}Usage examplesFor example a game bulletconst bullet = {  // define the bullet object    x : 0,    y : 0,    dx : 0,    dy : 0,    rot : 0,    dRot : 0,    lifeTime : 0,    dead : 0,};const MAX_BULLET_COUNT = 1000; // this limit is set depending on device performance an ensure a consistent frame ratevar bullets = []; // create the arraybullets.fastStack(MAX_BULLET_COUNT,bullet,dead); // allocate the object by creating all the bullets. and setting the                                                   // property name of the dead alive flag.to activate a bullet I get a free object and assign it the correct properties  var b = bullets.fNextFree();                                                 if(b !== undefined){ // make sure one is available    b.dead = false;    b.x = x;    b.lifeTime = 100; // how long to live    ... and so on...}To iterate the array I usebullets.fEach(function(b){    b.x += b.dx;    b.y += b.dy;    b.lifeTime -= 1;    b.dead = (b.lifeTime -= 1) > 0 ? true : undefined;    // when this returns if the flag property is undefined the object will not appear in the fEach loop until it is     // brought back to life.});There is also a second iterator that just serves out objects, such as in physics simulations where each item must be tested against all the othersSay the bullets can hit each other bullets.fEach(function(b1,i){    bullets.fEachQ(function(b2,j){        if(j > i){            //compare the two         }    }}So is this a ticking bomb or safe to extend further?                                
Extending Array to make a stack that bubbles unused objects up and active object down
javascript;array;memory management;extension methods