0

This is my JavaScript class:

class Animal{
  constructor(name, sound){
    this.name = name;
    this.sound = sound;
  }
  speak(){
     console.log(this.name + `${this.sound}`);
  }
}

I want to execute some code when first instance of Animal is created. I mean:

let dog1 = new Animal('n1', 's1'); //first instance - run my code
let dog2 = new Animal('n2', 'n2');// second instance - do nothing

Is it possible to do? Of course without changing Animal class in code above. Only using its constructor.

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • 3
    without changing Animal class? no. – yqlim Apr 22 '19 at 09:18
  • You can use java like static fields with babel. Its currently a Stage 3 proposal. See [this](https://stackoverflow.com/a/38727782/11168593) – jro Apr 22 '19 at 09:20
  • 1
    Use a static variable for class instance and check if it is null or not like we do in singleton classes. – Shubham Apr 22 '19 at 09:33

2 Answers2

5

Just put a check in the constructor:

let haveMadeFirstInstance = false;
class Animal{
  constructor(name, sound){
    this.name = name;
    this.sound = sound;
    if (!haveMadeFirstInstance) {
      console.log('First instance - running some code!');
      haveMadeFirstInstance = true;
    }
  }
  speak(){
     console.log(this.name + `${this.sound}`);
  }
}

console.log('About to create dog1');
let dog1 = new Animal('n1', 's1');
console.log('dog1 has been created');
let dog2 = new Animal('n2', 'n2');
console.log('dog2 has been created');

If you want the custom code to be encapsulated, feel free to put the class in an IIFE:

const Animal = (() => {
  let haveMadeFirstInstance = false;
  return class Animal{
    constructor(name, sound){
      this.name = name;
      this.sound = sound;
      if (!haveMadeFirstInstance) {
        console.log('First instance - running some code!');
        haveMadeFirstInstance = true;
      }
    }
    speak(){
       console.log(this.name + `${this.sound}`);
    }
  }
})();

console.log('About to create dog1');
let dog1 = new Animal('n1', 's1');
console.log('dog1 has been created');
let dog2 = new Animal('n2', 'n2');
console.log('dog2 has been created');

If you cannot modify the original class at all, and you also can't control when the first instance is created, then no, what you're looking to do is not possible.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • No, nothing other than the class constructor itself runs when the class is instantiated, so there's no way to hook into the instantiation unless you change the code in the constructor, or the code where the instantiation is done. – CertainPerformance Apr 22 '19 at 10:45
0

You can use a static property like this:

class Animal{

  constructor(name, sound){
    if(!Animal.instance) {
      console.log('First instance');
      this.name = name;
      this.sound = sound;
      Animal.instance = this;
    }
  }
  speak(){
     console.log(this.name + `${this.sound}`);
  }
}

let dog1 = new Animal('n1', 's1'); //first instance - run my code
let dog2 = new Animal('n2', 'n2');// second instance - do nothing

console.log('dog1: ', dog1);
console.log('dog2: ', dog2);
Fraction
  • 11,668
  • 5
  • 28
  • 48