Search code examples
javascripttostring

js object check if toString is defined


I am building a json formatter application. and I am very much confused by the toString method.

let's say I have an object. I parse it into a ul li Dom tree to illustrate. and I add a label based on the variable type.

function getText(val){
    v = val.toString();
    let p = document.createElement('span');
    p.innerText = v;
    return p;
}

it works fine for common types such as string, number, etc. but, when working with user defined object:

f = new TestClass();
console.log(getText(f));
{/* <span>[object Object]</span> */}

it produced a strange result. I have read relevant posts such as Overwriting toString function, and understand how it works.

basically, I understand javascript object's toString method the same as python's dunder __str__, for example, when something like:

`${f}`

is implemented TestClass.toString is called. then I tried to see where it is defined, what is the base class it inherits from, but I got nothing. super is not allowed in this context.


for user defined object, how can I determine whether a costume toString is defined on instance or not?

something like:

class TestClass1{
    
}

class TestClass2{
    toString(){

    }
}

console.log(new TestClass1().toString === undefined)
// should return true
console.log(new TestClass2().toString === undefined)
// should return false


Solution

  • You can check in their prototype if the toString() is the same as Object's or not:

    TestClass.prototype.toString === Object.prototype.toString
    

    Or, via an instance:

    // preferred method:
    Object.getPrototypeOf(testClassInstance).toString === Object.prototype.toString
    // alternative accessing __proto__ directly:
    testClassInstance.__proto__.toString === Object.prototype.toString
    

    Demo:

    class TestClass {
      toString() { return 'I am TestClass'; }
    }
    const tc = new TestClass();
    
    class ClassWithoutToString { }
    const cwts = new ClassWithoutToString();
    
    console.log(
      TestClass.prototype.toString === Object.prototype.toString,
      ClassWithoutToString.prototype.toString === Object.prototype.toString
    );
    console.log(
      Object.getPrototypeOf(tc).toString === Object.prototype.toString,
      Object.getPrototypeOf(cwts).toString === Object.prototype.toString
    );