0

I currently have an object that adds itself to an array whenever a new one is created. Eventually, I want to remove all of the references in the array so I can add new ones.

I've created an object method (this.removeFromArray()) that looks for itself in the array and splices itself out. removeAll() runs a for loop that makes each object in the array run removeFromArray(), so I expect that when I try to read out the items in the array, I should get nothing.

Instead, depending on the amount of objects created, I get one or two left behind. How can I fix this and have all objects in the array cleared out?

var objArray = [];

function obj(name) {
  objArray.push(this);
  console.log("Created "+name);

  this.name = name;
  this.removeFromArray = function() {
    objArray.splice(
      objArray.findIndex(function(e) {
        return e == this;
      }),
      1
    );
  }
}

function removeAll() {
  for (var i = 0; i <= objArray.length - 1; i++) {
    objArray[i].removeFromArray();
  }
}

var foo = new obj("foo");
var bar = new obj("bar");
var cat = new obj("cat");
var dog = new obj("dog");
var bird = new obj("bird");

removeAll();

for (var i = 0; i <= objArray.length-1; i++) { //Check the values in the array for leftovers
  console.log(objArray[i].name);
}

//Expected nothing in the console but the creation messages, got foo and bar instead

5
  • 3
    This is the age old problem of mutating an array while you're iterating it. When you remove an item, it gets removed (obviously), so now the array has changed from that point forward, but your i counter has not. Commented Feb 24, 2018 at 15:56
  • 3
    ...if you want to remove all the members, just do objArray.length = 0 Commented Feb 24, 2018 at 15:57
  • 3
    objArray = []? Commented Feb 24, 2018 at 15:57
  • Thanks, I thought array.length was a read-only value. I'll try it Commented Feb 24, 2018 at 15:58
  • 2
    @AyushGupta: Be careful with that one. If there are other variable references to the original array, they won't be emptied. Commented Feb 24, 2018 at 16:03

2 Answers 2

1

If you want to simply delete all the created object, edit removeAll() function like below:

Note that you have to create a variable for objArray.length, not directly put the objArray.length to for() loop.

function removeAll() {
  var len = objArray.length;
  for (var i = 0; i <= len - 1; i++) {
    objArray.splice(0,1);
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

still more complicated than objArray.length = 0 or objArray = []
Or objArray.splice(0,objArray.length); is OK too. But the code above can explain why there are 2 object left behind in OP's example.
1

better way to achieve this would be to utilize inheritance through prototype. it is better than creating a function inside the constructor object.

var objArray = [];

function Obj(name) {
    this.name = name;
    objArray.push(this);
}

Obj.prototype.removeFromArray = function() {
    var i = -1,
    len = objArray.length,
    removed = null;
    while (++i < len) {
        if (objArray[i] === this) {
            removed = objArray.splice(i, 1);
            removed = null; //nullify to free memory, though not that necessary
            break;
        }
    }
};

Obj.prototype.removeAll = function() {
    var len = objArray.length,
    removed = null;
    //note that i started from the last item to remove to avoid index out of range error
    while (--len >= 0) {
        removed = objArray.splice(len, 1);
        removed = null; //nullify to free memory, though not that necessary
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.