Get all instances of class in Javascript

2019-01-24 18:23发布

I thought there would already be an answer for this but I can't seem to find one.. How can I run a particular class method on all instances of this class in Javascript?

This has to be done in a situation where I do not know the names of the instances. I think I could use some sort of static variable inside my class to store all instances, but this doesn't seem to exist in JS

So how to call my method on all existing instances of my class? Note : just for clarification : I'm not speaking about CSS classes, I'm speaking about objects.

Edit : By Class in Javascript, I mean the creation of a new object on a function:

function something()
{
}

var instance = new something();

5条回答
Summer. ? 凉城
2楼-- · 2019-01-24 18:59

You'll have to provide a custom implementation.

I would do something like this :

function Class() {
    Class.instances.push(this);
};
Class.prototype.destroy = function () {
    var i = 0;
    while (Class.instances[i] !== this) { i++; }
    Class.instances.splice(i, 1);
};
Class.instances = [];

var c = new Class();
Class.instances.length; // 1
c.destroy();
Class.instances.length; // 0

Or like this :

function Class() {};
Class.instances = [];
Class.create = function () {
    var inst = new this();
    this.instances.push(inst);
    return inst;
};
Class.destroy = function (inst) {
    var i = 0;
    while (Class.instances[i] !== inst) { i++; }
    Class.instances.splice(i, 1);
};

var c = Class.create();
Class.instances.length; // 1
Class.destroy(c);
Class.instances.length; // 0

Then you could loop through all instances like so :

Class.each = function (fn) {
    var i = 0, 
        l = this.instances.length;
    for (; i < l; i++) {
        if (fn(this.instances[i], i) === false) { break; }
    }
};

Class.each(function (instance, i) {
    // do something with this instance
    // return false to break the loop
});
查看更多
家丑人穷心不美
3楼-- · 2019-01-24 19:02

You'll need to store a list of instances yourself:

function someClass(param) {

  // add to all
  if (this.constructor.all === undefined) {
    this.constructor.all = [this];
  } else {
    this.constructor.all.push(this);
  }

  // set param
  this.logParam = function() { console.log(param); };
}

var instance1 = new someClass(1);
var instance2 = new someClass(2);

for (var i = 0; i < someClass.all.length; i++) {
  someClass.all[i].logParam();
}

If memory leaks are a concern then you can create a method for deleting instances when you are done with them:

function someClass(param) {

  ...

  this.destroy = function() {
    var all = this.constructor.all;
    if (all.indexOf(this) !== -1) {
      all.splice(all.indexOf(this), 1);
    }
    delete this;
  }
}
查看更多
Lonely孤独者°
4楼-- · 2019-01-24 19:07

Sorry for such a late reply, but I found myself trying to achieve this and I think this may be a simpler answer.

Say you want all instances of class MyClass, only get instances created at top window level (not including instances created inside a closure):

for (var member in window)
{
    if (window[member] instanceof MyClass)
        console.info(member + " is instance of MyClass");
}
查看更多
仙女界的扛把子
5楼-- · 2019-01-24 19:16

You can create a static array and store it on your constructor function:

MyClass.allInstances = [];
MyClass.allInstances.push(this);

However, you need some way to figure out when to remove instances from this array, or you'll leak memory.

查看更多
我只想做你的唯一
6楼-- · 2019-01-24 19:16

In Chrome 62+ you can use queryObjects which will not work in native JavaScript code but in the console so is great for debugging.

class TestClass {};
const x = new TestClass();
const y = new TestClass();
const z = new TestClass();
queryObjects(TestClass)
查看更多
登录 后发表回答