0

It would really help debugging if all environments just logged the same content consistently! I am having a problem being able to just log the correct contents across different IDEs and browsers.

After reading various other posts (e.g. here), I’m trying to simply log the methods of an object. Take this code for example from this CodePen:

class User {
  constructor(name) {
    this.name = name;
  }
  
  fn() {
    return 'fn';
  }
  
  fn2() {
    return 'fn2';
  }
  
  static staticFn() {
    return 'static fn'
  }
}

const joe = new User('Joe')

console.log(joe)
console.log(joe.fn)
console.log(Object.getPrototypeOf(joe)) // the important part!

The methods fn and fn2 should at least be logged. If you copy the above code snippet and paste it into chrome’s JS console then it correctly logs everything, particularly the important part (the final log):

enter image description here

However, paste the same code into Safari’s JS console and the important part incorrectly logs as just User {}, not showing the object’s methods:

enter image description here

Additionally the CodePen’s important part just logs [object Object] {}:

enter image description here

And VSCode just logs {}.

So my question is how can you correctly log the methods of an object in all environments? It’s causing a nightmare trying to debug anything as some node code I have only runs in an IDE, unavailable to a browser.

This has come from a bug where I’m fetching an object from a mongo database that strangely doesn’t seem to have any methods despite the object having methods before being inserted into the database.

Any advice or debugging tips would be greatly appreciated, thank you.

user8758206
  • 2,106
  • 4
  • 22
  • 45

1 Answers1

1

How different environments log an object is implementation-defined, so as you've seen it tends to vary. When you create an instance of your User class, that object's methods will be:

  1. On the instances' prototype
  2. Non-enumerable

In the case of Chrome, it logs the object not just with its own properties, but also with the non-enumerable and enumerable properties on its prototype.

In Safari's case, it doesn't show non-enumerable properties on the object's prototype unless you expand the object and view its prototype explicitly. In my opinion, Safari's developer tools are outdated and have some strange quirks that make debugging unintuitive, so best to stay away from it if you can.

Web-based consoles, such as the one on CodePen, typically log objects by using JSON.stringify() and then append the stringified text to their own custom DOM console. When objects are stringified, non-enumerable properties and any properties on the prototype are ignored and not included in the string result. That's why typically you're better off looking at the browser console itself when it comes to viewing the contents of your object rather than a custom-made web console.

If you want to log all the methods, you can use Object.getOwnPropertyNames() and walk the prototype chain of your object (see below snippet for example). However, this usually isn't needed, and instead, using the console or debugger (which you can enter by using debugger) in something like Chrome, Firefox or VSCode will show you the correct properties of your object, eg: Image of VSCode debugger menu showing the joe object expanded on the left local variables panel showing the prototype methods, fn and fn2

class User {
  constructor(name) {
    this.name = name;
  }
  
  fn() {
    return 'fn';
  }
  
  fn2() {
    return 'fn2';
  }
  
  static staticFn() {
    return 'static fn'
  }
}

const joe = new User('Joe')
const getMethods = (obj) => {
  let curr = obj;
  while(curr !== Object.prototype) {
    const names = Object.getOwnPropertyNames(curr);
    for(const key of names)
      if(typeof curr[key] === "function")
        console.log(key, curr[key]);
    
    curr = Object.getPrototypeOf(curr);
  }
}

getMethods(joe);
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • that now logs correctly, thank you! I think the mongo findOne method just always returns an object that has no methods, even if the object inserted initially has methods – user8758206 Jun 12 '22 at 16:12