2

Is there a way to clear an object in Javascript? Specifically if an object has several member variables is there a simple way to reset each value?

function exampleObject() {
    this.valueA = "A"; 
    this.valueB = "B"; 
    this.myArray = [1,2,3];
}

So basically for an instance of the above reset the three members to empty strings and an empty array? I could easily prototype a member function for the object to do this and call it:

function exampleObject() {
    this.valueA = "A"; 
    this.valueB = "B"; 
    this.myArray = [1,2,3];
    exampleObject.prototype.resetAll = function() {
        this.valueA = ""; 
        this.valueB = ""; 
        this.myArray = [];
    }
}

However I want to do this for objects from a third-party library so adding a member function isn't realistic.

Gedalya
  • 899
  • 4
  • 16
  • 28
  • create an instance of the object with the variables you want it to have... then when you want to 'reset' it... `var thisObj = blankObj;` – xxcezz Jun 06 '14 at 20:09
  • Not built in, no. You'd probably want to write a function that recursively traverses an object and does what you want. – Qix - MONICA WAS MISTREATED Jun 06 '14 at 20:09
  • @xxcezz That works, but poses the problem of references; if the existing object is already referenced somewhere then you'll have to update all those references. – Qix - MONICA WAS MISTREATED Jun 06 '14 at 20:10
  • 1
    Then make a global resetThisTypeOfObject() function and do like @Qix said... but adding to a 3rd-party libraries prototypes isn't really that difficult either – xxcezz Jun 06 '14 at 20:11
  • 1
    hiding in plain sight: exampleObject.call(theInstance); returns init values of an object to the init values. – dandavis Jun 06 '14 at 20:18
  • Found this: http://stackoverflow.com/questions/5432967/how-to-iterate-over-inner-objects-property-in-an-object – Gedalya Jun 06 '14 at 20:27
  • "so adding a member function isn't realistic" so what? just make a function that has an object parameter – guest Jun 06 '14 at 20:30
  • What do you mean by reset? Clear all strings, empty all arrays, set all numbers to 0, etc.? – Retsam Jun 06 '14 at 20:31
  • Your example has the prototype defined in the wrong place: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Jun 07 '14 at 01:05

2 Answers2

2

It depends on what you mean by "reset". If you want to clear all properties to some default value based on property type, you could do something like this:

function resetObject(o) {
    for(var key in o) {
        if(!o.hasOwnProperty(key)) continue;
        var val = o[key];
        switch(typeof val) {
            case "string":
                o[key] = ""; break;
            case "number":
                o[key] = 0; break;
            case "boolean":
                o[key] = false; break;
            case "object":
                if(val === null) break;
                if(val instanceof Array) {
                    o[key] = []; break;
                }
                val = {}; 
                //Or recursively clear the sub-object
                //resetObject(val);
                break;
        }
    }
}
Retsam
  • 30,909
  • 11
  • 68
  • 90
  • 1
    except that instantly breaks any prototype methods on all instances the first time it's called... – dandavis Jun 06 '14 at 20:37
  • Good catch; should be `var key in Object.getOwnPropertyNames(o)`, fixed. – Retsam Jun 06 '14 at 20:41
  • 1
    now you're iterating an array of keys and clobbering Array.prototype, which ain't right... you need for and if, and hasOwnProperty() in the if. – dandavis Jun 06 '14 at 20:42
  • Whoops; yeah. I've been using too much lodash; I'm rusty on the quirks of the `for(prop in obj)` syntax. Should be fixed for real now. – Retsam Jun 06 '14 at 20:46
  • much better. that still replaces objects instead of emptying them, which may or may not matter. it would be better to clear arrays by setting length to 0, and objects as Object.keys(o).forEach(function(){delete o[a]; }). It also breaks Dates and RegExps, though how better to clear those types is not clear... – dandavis Jun 06 '14 at 20:51
  • Ehh, everything else you mention is in the realm of "undefined behavior"; I think doing a shallow reset and replacing sub-objects and arrays (look at their example code) is perfectly reasonable, and I didn't care to special case things like dates or RegExs, just for simplicity. – Retsam Jun 06 '14 at 20:59
  • it's a good solution to an unclear problem, i wasn't complaining ;) – dandavis Jun 06 '14 at 21:01
0

This might need a little tweaking if you have own properties which are again Objects (or functions), but you could do something like..

var resetMyObject = (function (Constr) {
    var defaults = new Constr();
    function has(o, k) {
        return Object.prototype.hasOwnProperty.call(o, k);
    }
    return function resetFunction(obj) {
        var k;
        for (k in obj) { // might want to iterate over ownPropertyNames instead
            if (has(obj, k)) {
                if (has(defaults, k)) {
                    obj[k] = defaults[k];
                } else {
                    delete obj[k];
                }
            }
        }
        return obj;
    };
}(MyObject)); // pass in the constructor to generate the function

resetMyObject(instanceOfMyObject);

For example, with MyObject = Array,

resetMyObject([1, 2, 3]); // [undefined × 3] (length non-enumerable property)
Paul S.
  • 64,864
  • 9
  • 122
  • 138