Search code examples
javascriptvariablescastingeval

Looping through variable names as strings, and destroying them


I have a list of variables (let's call them obj1, obj2, etc.). I would like to loop through all of them and, if they exist, destroy them. Obviously .destroy() is an external call.

Why does this work:

for (var i = 0; i < 10; i++) {
    var obj = "obj" + i.toString();
    if (window[obj]) {
        window[obj].destroy();
    }
}

But this doesn't:

var objs = [];
for (var i = 0; i < 10; i++) {
    objs.push("obj" + i.toString());
    if (objs[i]) {
        objs[i].destroy(); //throws a TypeError
    }
}

And is there a better solution that's more like the second, and doesn't involve accessing global scope via window? Please don't say eval().


Solution

  • objs.push("obj" + i.toString()); will push a string to the objs array. But strings don't have a .destroy property. In comparison, window["obj" + i.toString()] tries to reference a property on the window object by that name. (The value in that property, or undefined, will be pushed to objs)

    It would be better to restructure your script so that rather than searching through the window object for variables of a certain name, you instead put all the related variables into an array at the start, so that you can then iterate through the array and destroy() them directly:

    const objs = [
      <someObj1>,
      <someObj2>,
      ...
    ];
    objs.forEach(obj => obj.destroy());