Correct way to reset or clear a Javascript object?

17,746

Solution 1

This

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);

overwrites the the property which holds the ParamHash() constructor function with an instance object. You could get the constructor back via

utils.ParamHash.constructor

but the cleaner way would be to not overwrite it in the first place and use a seperate property to hold the instance.


I don't know the exact problem Cerebrus is trying to solve, so there might be valid reasons for what he's doing. But in my opinion, his solution is overly complicated. I'd do something like this:

function MyUtils() {
    this.x = getComplexData();
    this.y = doSomeInitialization();
    this.params = {};
}

MyUtils.prototype.doSomething = function() {
    for(var prop in this.params) {
        if(this.params.hasOwnProperty(prop)) {
            // do stuff
        }
    }
};

var utils = new MyUtils;
utils.params = { a : 1, b : 2 };
utils.doSomething();

The check for hasOwnProperty() is unnecessary if you can be sure that no one messed with Object.prototype.


Some additional comments:

  • in JavaScript, normally only the names of constructor functions are capitalized
  • items shouldn't be an array, but a plain object, ie this.items = {};

Solution 2

when you did this

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);

you replaced the ParamHash constructor function with an object instance. Subsequent new ParamHash() fails because utils.ParamHash is no longer a constructor function.

Try this:

var utils = new MyUtils();
utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2);
utils.DoSomething();
Share:
17,746
Cerebrus
Author by

Cerebrus

I've been moderating the DotNetDevelopment Google Group for the past 5 years and have been extremely active within the Group.

Updated on June 27, 2022

Comments

  • Cerebrus
    Cerebrus almost 2 years

    I have a Javascript class that contains a few functions and member objects:

    function MyUtils()
    {
      // Member Variables (Constructor)
      var x = getComplexData();
      var y = doSomeInitialization();
    
      // Objects
      this.ParamHash = function()
      {
        // Member variables
        this.length = 0;
        this.items = new Array();
    
        // Constructor
        for (var i = 0; i < arguments.length; i += 2)
        {
          // Fill the items array.
          this.items[arguments[i]] = arguments[i+1];
          this.length++;
        }
      }
    
      // Functions
      this.doSomething = function()
      {
        // Do something.
        // Uses the items in the ParamHash object.
        for (var i in this.ParamHash.items)
        {
          // Really do something!
        }
    
        // Clear the ParamHash object -- How??
      }
    }
    

    This is invoked in the following manner:

    // First call - works fine.
    var utils = new MyUtils();
    utils.paramHash = new utils.ParamHash("a", 1, "b", 2);
    utils.doSomething();
    
    // Don't want to re-initialize.
    // utils = new MyUtils();
    
    // Consequent call - crashes ["Object doesn't support this action."].
    utils.paramHash = new utils.ParamHash("c", 3);
    utils.doSomething();
    

    The problem arises from the restriction that I want to reuse the same utils object throughout the code without having to re-initialize it. Also, I want the ParamHash object to be recreated from scratch everytime I call it. However, consequent calls to the ParamHash constructor throw an error "Object doesn't support this action." At this stage, I can see that the utils.paramHash object still contains the old values ("a", "b").

    I have tried various ways to clear the ParamHash object such as setting it's items and length to null, popping items from the array. Nothing seemed to work until I used the following way (in the doSomething() function):

    this.paramHash.items = new Array();
    this.paramHash.length = 0;
    

    This seems wrong because what if I had a lot of member variables... would I have to reset each of them individually? So, the question is: What is the best way to reset the ParamHash object to the initial state? I'm sure hoping that there is a cleaner/more direct way. Something like :

    // Doesn't work! :-(
    this.paramHash = new function() {};
    

    EDIT: I'm looking for a cross-browser solution - One that works atleast in IE6+ and FF 2+.


    Solution: Thanks to Cristoph, I was able to do it by creating a separate variable/property within MyUtils which only holds the instance of the ParamHash function.

    function MyUtils()
    {
      // Same ol' stuff.
      var myParamHash;
    }
    
    // First call - works fine.
    var utils = new MyUtils();
    utils.myParamHash = new utils.ParamHash("a", 1, "b", 2);
    utils.doSomething();
    
    // Consequent call - works fine now.
    utils.myParamHash = new utils.ParamHash("c", 3);
    utils.doSomething();
    
    • Christoph
      Christoph about 15 years
      I added a simpler solution to my answer; don't know what problem you're trying to solve, so your code might be better suited...
  • Cerebrus
    Cerebrus about 15 years
    I have, even though I would have been surprised if that had worked. It says "Function expected." :-(
  • Chetan S
    Chetan S about 15 years
    If you omit the new keyword, it doesn't create a new object. It just runs the constructor function in a global context (setting all the properties to the window object)!
  • Cerebrus
    Cerebrus about 15 years
    Thanks, Chetan. That does not throw an error, but then the instance or the parameters are not available within the DoSomething() function which is part of the class. I need to do the reset from within the DoSomething() function.
  • Cerebrus
    Cerebrus about 15 years
    Can you provide an example of how I can use the retrieved constructor (using the constructor property) to reset the object?
  • Christoph
    Christoph about 15 years
    utils.ParamHash = utils.ParamHash.constructor will undo the assignment, ie after that you can assign new values via utils.ParamHash = new utils.ParamHash("c", 3, "d", 4)
  • Cerebrus
    Cerebrus about 15 years
    Thank you. I have edited my question to include the final solution I used.
  • Cerebrus
    Cerebrus about 15 years
    Because I neglected to create the property within the MyUtils class. I was adding the property dynamically as @Chetan's answer seemed to suggest. See my edited question.