Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created October 15, 2011 14:44
Show Gist options
  • Save cowboy/1289665 to your computer and use it in GitHub Desktop.
Save cowboy/1289665 to your computer and use it in GitHub Desktop.
Shitty destructors for JavaScript!
function Thing(context, name) {
this.context = context;
this.name = name;
this.init();
this.startTheWorstGarbageCollectorEver();
}
Thing.prototype.startTheWorstGarbageCollectorEver = function() {
var id = setInterval(function() {
if (!this.context[this.name]) {
clearInterval(id);
this.destroy();
}
}.bind(this), 1000);
};
Thing.prototype.init = function() {
this.clickfn = function() {
console.log('clicked');
};
document.addEventListener('click', this.clickfn);
};
Thing.prototype.destroy = function() {
document.removeEventListener('click', this.clickfn);
};
// Create an instance:
window.myThing = new Thing(window, 'myThing');
// <click> (logs "clicked")
// Delete the "primary" reference:
delete window.myThing;
// Wait ~1 second.
// <click> (doesn't log!!!)
// Amazing!
@goofballLogic
Copy link

"worst ever" eh?
I feel a competition coming on...

@goofballLogic
Copy link

// N.B. Extremely thread safe
function EvenWorseGarbageCollector() {
    var leakCentral = [],
        fWasDeleted = function(spec) { return !spec[0].hasOwnProperty(spec[1]); },
        sweepHandle = null;
        ;

    this.sweep = sweep;
    this.enleak = enleak;

    function sweep() {
        console.log("sweep");
        for ( var i = 0; i < leakCentral.length; i++ ) {
            if( fWasDeleted(leakCentral[i]) )
                destroy(leakCentral[i]);
        }
        if ( leakCentral.length > 0 ) startDestroying();
        else stopDestroying();
    }

    function destroy(spec) {
        leakCentral.splice(leakCentral.indexOf(spec), 1);
        if ( "function" == typeof(spec[2].destroy) ) spec[2].destroy();
    }

    function enleak(spec) {
        leakCentral.push(spec);
        startDestroying();
    }

    function startDestroying() {
        if ( !sweepHandle ) sweepHandle = setInterval( sweep, 1000 );
    }

    function stopDestroying() {
        if ( !sweepHandle ) return;
        clearInterval( sweepHandle );
        sweepHandle = null;
    }
}

Object.prototype.activateDispose = function(context, key) {
    if( !Object.hasOwnProperty("collector") )
        Object.collector = new EvenWorseGarbageCollector();

    Object.collector.enleak( [ context, key, this ] );
};

function Thing(context, name) {
    this.init();
    this.activateDispose(context, name);
}

Thing.prototype.init = function() {
    this.clickfn = function() {
        console.log('clicked');
    };

    document.addEventListener('click', this.clickfn);
};

Thing.prototype.destroy = function() {
    document.removeEventListener('click', this.clickfn);
    console.log("destroyed");
};

// Create an instance:
window.myThing = new Thing(window, 'myThing');
// <click> (logs "clicked")

// Delete the "primary" reference:

delete window.myThing;
// Wait ~1 second.
// <click> (doesn't log!!!)

// Amazing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment