Calling code: create a Foo class that keeps track of the number of instances of shared objects

I am trying to solve a problem with the code for an application, but I am stuck and would appreciate any help.

Question. Create a class Foo that has a refCount method. Calling refCount in a class or in any of its instances should return the number of shared instances.

Example:

var f1 = new Foo(); f1.refCount(); // should be 1 Foo.refCount(); // should be 1 var f2 = new Foo(); f1.refCount(); //should be 2 f2.refCount(); // should be 2 Foo.refCount(); // should be 2 

I have something like this so far:

 function Foo() { this.refCount = function() { ++Foo.prototype.refs; return Foo.prototype.refs; } } Foo.prototype.refs = 0; 

I also tried using IIFE to attach the method to the class itself, but then I was not able to figure out how to create new instances.

+7
javascript
source share
3 answers
 function Foo() { Foo.__n++; } Foo.refCount = function() { return Foo.__n; } Foo.__n = 0; Foo.prototype.refCount = Foo.refCount; 

Output:

 > var f = new Foo(); console.log(f.refCount(), Foo.refCount()); 1 1 > f = new Foo(); console.log(f.refCount(), Foo.refCount()); 2 2 > f = new Foo(); console.log(f.refCount(), Foo.refCount()); 3 3 
+1
source share

This is impossible to do.

JavaScript is object-oriented, and classes in JavaScript are just an illusion created by setting the prototype property of an object to a specific prototype object.

The new Foo () syntax is syntactic sugar for installing this prototype. And your best option, as others have shown, is to perform refCounting in the constructor function, effectively counting the number of times it called. Then you can save the count variable in the prototype either as a property of the constructor function itself or in IIFE (see below) and return its value in the refCount function.

But if people start dynamically changing the prototypes of objects, objects can change the class, and I don’t think that the refCount function does not know that this happened.

 var Foo (function(){ var n = 0; Foo = function Foo() { this.refCount = Foo.refCount; n++; }; Foo.refCount = function() { return n; } })() function Bar() {} f = new Foo(); console.log("created f, refCount = 1", f instanceof Foo, f.refCount(), Foo.refCount()); g = new Foo(); console.log("created g, refCount = 2", f instanceof Foo, g instanceof Foo, f.refCount(), g.refCount(), Foo.refCount()); g.__proto__ = Bar.prototype; console.log("turned g into a Bar", f instanceof Foo, g instanceof Foo) console.log("but refCount still is 2", Foo.refCount()); h = Object.assign(f) console.log("created h without calling the constructor", h instanceof Foo) console.log("But refCount still is 2", h.refCount(), Foo.refCount()) 

Look at jsbin

See https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain and How to set a prototype JavaScript object that has already been instantiated?

+2
source share
 var n = refs = 0; function refCount() { refs = ++n; return n; } function Foo() { refCount() } var f1 = new Foo(); console.log(refs); var f2 = new Foo(); console.log(refs); 
0
source share