Estoy tratando de resolver un desafío de código para una aplicación de trabajo, pero estoy atascado y agradecería cualquier ayuda.

Pregunta: Cree una clase Foo que tenga un método llamado refCount. Llamar a refCount en la clase o en cualquiera de sus instancias debería devolver cuántas instancias totales existen.

Ejemplo:

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

Tengo algo como esto hasta ahora:

function Foo() {

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

}

Foo.prototype.refs = 0;

También intenté usar un IIFE para adjuntar un método a la clase en sí, pero luego no pude descubrir cómo crear nuevas instancias.

7
user6317504 11 may. 2016 a las 01:38

3 respuestas

La mejor respuesta
function Foo() {
    Foo.__n++;
}
Foo.refCount = function() { return Foo.__n; }
Foo.__n = 0;
Foo.prototype.refCount = Foo.refCount;

Salida:

> 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
OneOfOne 10 may. 2016 a las 22:59

Eso no se puede hacer.

JavaScript está orientado a objetos, y las clases en JavaScript son solo una ilusión, creada al establecer la propiedad prototipo de un objeto a un cierto objeto prototipo.

La nueva sintaxis de Foo () es azúcar sintáctica para establecer ese prototipo. Y su mejor opción, como han demostrado otros, es hacer el refCounting en la función de constructor, contando efectivamente la cantidad de veces que se llamó. Luego puede almacenar la variable de conteo en el prototipo o como una propiedad de la función constructora o en un IIFE (ver más abajo), y devolver su valor en la función refCount.

Pero si las personas comienzan a cambiar dinámicamente los prototipos del objeto, los objetos pueden cambiar de clase y no se me ocurre ninguna forma para que la función refCount sepa que eso sucedió.

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

Véalo en JSBin

Consulte https://developer.mozilla.org/en/docs/Web/JavaScript / Inheritance_and_the_prototype_chain y ¿Cómo configurar el prototipo de un objeto JavaScript que ya ha sido instanciado?

2
Community 23 may. 2017 a las 10:29
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
guest271314 10 may. 2016 a las 22:49