1

Let me explain my question with an example. Let's define some class and its instance:

class MyClass {
  a() { return 1 }
}

const myInstance = new MyClass()

console.log(MyClass) returns "[class MyClass]".

console.log(myInstance) returns "MyClass {}"

Where does console.log get these values from? I tried several ways to get it, but they return different:

For the class:

console.log(MyClass.toString()) // class MyClass {
                                //   a() { return 1; }
                                // }

console.log(MyClass.constuctor.toString()) // function Function() { [native code] }

console.log(MyClass.constuctor.name) // Function

console.log(Object.prototype.toString.call(MyClass)) // [object Function]

console.log(MyClass[Symbol.toStringTag]) // undefined

And for the instance:

console.log(myInstance.toString()) // [object Object]

console.log(myInstance.constuctor.toString()) // class MyClass {
                                              //   a() { return 1; }
                                              // }


console.log(myInstance.constuctor.name) // MyClass

console.log(Object.prototype.toString.call(MyClass)) // [object Object]

console.log(myInstance[Symbol.toStringTag]) // undefined

So, let's imagine that my goal is to write a function that returns "class MyClass" when passing a class, and returns "MyClass {}" when passing an instance. How can I do this? Of course, similar data is in the results of the examples above and I can use it. However, I suspect there is a much simpler solution.

  • 1
    See [`Symbol.toStringTag`](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag). `MyClass.constuctor` has nothing to do with the class. `MyClass` is the constructor itself. – Sebastian Simon Apr 03 '22 at 08:19
  • 1
    Not sure to understand. You are deciding. myInstance = new MyClass() means "create an instance of class MyClass and assign it to myinstance". Aa class and an instance of that class are two different things – SimoneB Apr 03 '22 at 08:22
  • I tried it, but MyClass[Symbol.toStringTag] and myInstance[Symbol.toStringTag] are undefined. My goal is to write a function that returns "class MyClass" when passing a class, and returns "MyClass {}" when passing an instance. How can I do this? Of course, similar data is in the results of the examples above and I can use it. However, I suspect there is a much simpler solution. – Alexander Paschenko Apr 03 '22 at 08:32
  • 1
    It's Node.js, not a browser. But Node.js using the same v8 engine as Chromium browser. – Alexander Paschenko Apr 03 '22 at 08:43
  • 1
    Just check the .prototype, instance will return undefined, class will return object. .constructor.name will return "MyClass" for the instance and Function for the class – SimoneB Apr 03 '22 at 08:53
  • Thank you, of course I can do that. But it seems to me that these values are already contained in the class and in the instance, it is unlikely that the console.log constructs them in this way. – Alexander Paschenko Apr 03 '22 at 09:00
  • 1
    I doubt you can affect much on the console output. Console analyzes the logged object in its own way. You can set `Symbol.toStringTag`, usually it's read with `Object.prototype.toString.call(obj)`, see more information at the MDN page Sebastian has linked to. – Teemu Apr 03 '22 at 09:00
  • Thanks. I don't want to change the console output, but reproduce its behavior – Alexander Paschenko Apr 03 '22 at 09:03
  • 1
    Console can access an object much deeper than ECMAScript language features, all the information is not available in JS. Ex. a class is actually a function. You can [create your own](https://jsfiddle.net/wua2emk7/) toString/valueOf accessors for objects, and use those in your program (they're still not logged, though). – Teemu Apr 03 '22 at 09:18
  • Thanks. This is a really interesting solution. The only doubt is purely architectural: monkey-patching is frowned upon in Javascript, so it's best to avoid chaning built-in language objects. – Alexander Paschenko Apr 03 '22 at 09:27
  • 1
    It's not monkey-patching (the prototype is not touched), it's just shadowing the method in instances and in the class. This is commonly used practice, which is often used when you're creating objects behaving like instances of `Date`. – Teemu Apr 03 '22 at 09:30
  • Many thanks. Yes, your suggestion is the best in my opinion. – Alexander Paschenko Apr 03 '22 at 09:36
  • 1
    The nodejs output still looks weird, I don't have a nodejs at hands right now, but `console.log(Object.prototype.toString.call(MyClass));` returns `[object Function]` in Chromium browser console. There seems to be some differencies between the consoles. – Teemu Apr 03 '22 at 09:41

0 Answers0