Search code examples
javascriptecmascript-6es6-classprototypal-inheritance

Is there a Class equivalent to prototype attributes?


If I have the following code:

function Thing() {}
Thing.prototype.cache = {};

var a = new Thing();
var b = new Thing();

a.cache === b.cache // true

How might I re-write this using proper Classes?

I know about public class fields, but those are defined on the instance rather than on the class prototype.

// For Example:
class Thing {
  cache = {}
}

var a = new Thing();
var b = new Thing();

a.cache === b.cache // false

Solution

  • There's no class syntax to put non-methods on the prototype, you'll have to slap them on afterwards, like this:

    class Thing {}
    Thing.prototype.cache = {}
    
    // Example usage //
    
    const thing1 = new Thing()
    const thing2 = new Thing()
    thing1.cache.x = 2
    console.log(thing2.cache.x)

    However, putting mutable data on the prototype is seen by many as magical and difficult to follow. Here's another way to achieve a very similar effect.

    // This can alternativly be a static, private variable on the class.
    const thingCache = {}
    
    class Thing {
      cache = thingCache
    }
    
    // Example usage //
    
    const thing1 = new Thing()
    const thing2 = new Thing()
    
    thing1.cache.x = 2
    console.log(thing2.cache.x)

    But, what I would really recommend is to just make this property a static property on the class - that's what static properties are for, sharing a single piece of data between many instances.

    class Thing {
      static cache = {}
    }
    
    // Example usage //
    
    Thing.cache.x = 2
    console.log(Thing.cache.x)
    
    // In some rare scenarios where you only have the instance,
    // and not the original class, you can still retrieve the original class
    
    const thing1 = new Thing()
    const thing2 = new Thing()
    
    thing1.constructor.cache.x = 2
    console.log(thing2.constructor.cache.x)