Skip to content
Advertisement

JavaScript: Overwrite property defined in constructor for whole class

I am trying to overwrite the function of a class:

class MyClass {
  constructor() {
    // more code
  }

  myFunction = function() {
    console.log('not this')
  }
}

// can't change the code above

MyClass.prototype.myFunction = function() {
  console.log('it should print this')
}

new MyClass().myFunction()

But Babel compiles the above to this:

class MyClass {
  constructor() {
    // more code

    this.myFunction = function () {
      console.log('not this');
    };
  }
}

// can't change the code above

MyClass.prototype.myFunction = function () {
  console.log('it should print this');
};

new MyClass().myFunction();

Because the function is defined as a property in the original code, Babel puts that definition in the constructor. If I understand correctly prototype only contains functions, not all properties. Because the constructor runs after the object was derived from the prototype, I can’t use the prototype to overwrite that function.

My second try was overwriting the constructor:

class MyClass {
  constructor() {
    // more code
  }

  myFunction = function () {
    console.log('not this')
  }
}

// can't change the code above

let oldConstructor = MyClass.prototype.constructor
MyClass.prototype.constructor = function() {
  // call old constructor first, it will set myFunction
  oldConstructor()

  // now overwrite myFunction
  this.myFunction = function () {
    console.log('it should print this')
  }
}

new MyClass().myFunction()

Well, let’s try… Compile with Babel, save it to test.js and run:

~> node test.js
not this

I tried to make the question as general as possible. More background information on why I can’t change the class in my specific case: The class is actually from a library I’m using and other packages I use depend on that library too. MeteorJS requires packages to specify the exact version and source of their dependencies, which is why I can’t use a fork: I would have to fork every package that depends on this library.

Advertisement

Answer

In fact you are changing your class, but it is “not taking” effect because how javascript interpreter looks for information inside its objects. First, properties inside object, then prototype chain.

In your first example, if you “remove” local propertie, you change takes effect. Example:

class MyClass {
  constructor() {
    // more code

    this.myFunction = function () {
      console.log('not this');
    };
  }
}

// can't change the code above

MyClass.prototype.myFunction = function () {
  console.log('it should print this');
};

const obj = new MyClass();
delete obj.myFunction;
obj.myFunction();

https://jsbin.com/gixufadewu/edit?js,console

Advertisement