Search code examples
javascriptclassoverridingtostring

Override toString() of a property of a class - javascript


I'm trying to (re)learn OOP in javascript. I'd like to override the toString method of an array that is a property of my object/class.
This solution works for simple arrays, but not as I'd like for the one in my object/class.
I got it working with __proto__ but it seems to be deprecated. I'd like to not override the Array.toString, only the Solver.foo.toString. I'm probably missing something obvious. Thanks.

//solution that works on simple array
let version = [0, 3, 0];

version.toString = function() {
  return this.join('foo');
};

console.log("simple array: " + version);

//Same solution for my object/class
class Solver {
  constructor(arr) {
    this.foo = arr;
    this.foo.toString = function() {
      return this.join('foo');
    };
  };
}

//that works here
let bar = new Solver([0, 3, 0]);
console.log("property array: " + bar.foo);
//but not here
bar.foo = [0, 3, 0];
console.log("property array: " + bar.foo);


Solution

  • I suggest you make use of getters and setters for JavaScript classes. With a setter, a simple assignment becomes a call to a internal method of the class, you can leverage this to always make sure you mutate the value to have the updated toString function. A getter will help you call on the value from the outside.

    Here is a working example:

    class Solver {
        constructor(arr) {
            this.foo = arr;
        };
        
        set foo(arr) {
            this.fooValue = arr.slice(); // copying to avoid mutating the outside array
            this.fooValue.toString = function() {
                return this.join('foo');
            };
        }
        
        get foo() {
            return this.fooValue;
        }
    }
    
    let bar = new Solver([0, 3, 0]);
    console.log("constructor property array: " + bar.foo);
    const outsideArray = [0, 3, 1];
    console.log("outside property array: " + outsideArray);
    bar.foo = outsideArray;
    console.log("setter property array: " + bar.foo);