Vincent Duprez
Vincent Duprez

Reputation: 3892

Get all instances of class in Javascript

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();

Upvotes: 13

Views: 33668

Answers (6)

0BLU
0BLU

Reputation: 718

In Chrome 62+ you can use queryObjects from the console API - which will not work in native JavaScript code but in the console so it's great for debugging.

class TestClass {};
const x = new TestClass();
const y = new TestClass();
const z = new TestClass();
queryObjects(TestClass)

Upvotes: 15

honzar
honzar

Reputation: 124

Keyword 'static' could be used in classes now (but check support), ...

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

class Point{
    constructor(x, y){
        this.x = x;
        this.y = y;
        Point.all.push(this);
    }
    destroy(){
        let i = Point.all.indexOf(this);
        Point.all.splice(i, 1);
    }
    static all = [];
}

var p1 = new Point(1, 2);
var p2 = new Point(54, 33);
var p3 = new Point(297, 994);

console.log(JSON.stringify(Point.all)); //[{"x":1,"y":2},{"x":54,"y":33},{"x":297,"y":994}]

p2.destroy();
console.log(JSON.stringify(Point.all)); //[{"x":1,"y":2},{"x":297,"y":994}]

Upvotes: 5

Koas
Koas

Reputation: 420

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");
}

Upvotes: 9

user1636522
user1636522

Reputation:

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
});

Upvotes: 11

olleicua
olleicua

Reputation: 2118

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;
  }
}

Upvotes: 2

SLaks
SLaks

Reputation: 887777

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.

Upvotes: 22

Related Questions