Correct way to reset or clear a Javascript object?
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, iethis.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();
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, 2022Comments
-
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 theParamHash
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 about 15 yearsI 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 about 15 yearsI have, even though I would have been surprised if that had worked. It says "Function expected." :-(
-
Chetan S about 15 yearsIf 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 about 15 yearsThanks, 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 about 15 yearsCan you provide an example of how I can use the retrieved constructor (using the constructor property) to reset the object?
-
Christoph about 15 years
utils.ParamHash = utils.ParamHash.constructor
will undo the assignment, ie after that you can assign new values viautils.ParamHash = new utils.ParamHash("c", 3, "d", 4)
-
Cerebrus about 15 yearsThank you. I have edited my question to include the final solution I used.
-
Cerebrus about 15 yearsBecause 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.